visual valid remarks name method example documentacion comment comentarios c# .net nullreferenceexception nullable

valid - summary param name c#



¿Cuándo exactamente los tipos anulables lanzan excepciones? (4)

Esto es porque int? x = null; int? x = null; Básicamente, crea una instancia del tipo de valor System.Nullable<int> , con un valor null "interno" (puede verificarlo a través de la propiedad .HasVaue ). Cuando se invoca GetHashCode , el Nullable<int>.GetHashCode es el candidato candidato (ya que el método es virtual), ahora tenemos una instancia de Nullable<int> y ejecutamos su método de instancia, perfecto.

Cuando se invoca GetType , el método no es virtual, por lo que la instancia de Nullable<int> se System.Object primero en System.Object , de acuerdo con el documento , y el valor encuadrado es null , de ahí la NullReferenceException .

Considere el siguiente código:

int? x = null; Console.Write ("Hashcode: "); Console.WriteLine(x.GetHashCode()); Console.Write("Type: "); Console.WriteLine(x.GetType());

Cuando se ejecuta, escribe que Hashcode es 0 , pero falla con NullReferenceException en un intento de determinar el tipo de x . Sé que los métodos llamados en tipos anulables realmente son llamados en valores subyacentes, por lo que esperaba que el programa fallara durante x.GetHashCode() .

Entonces, ¿cuál es la diferencia fundamental entre estos dos métodos y por qué no falla el primero de ellos?


La implementación de Nullable<T>.GetHashCode() es la siguiente:

public override int GetHashCode() { if (!this.HasValue) { return 0; } return this.value.GetHashCode(); }

Entonces, cuando el valor es nulo, siempre obtendrá 0 .

x.GetType() es igual que null.GetType() que arrojará la Object reference not set to an instance of an object


Para aclarar la respuesta correcta de Danny Chen:

  • Nullable<T> es un tipo de valor. El tipo de valor consta de un valor bool, que indica nulidad (falso significa nulo) y una T, el valor.
  • A diferencia de todos los demás tipos de valor, los tipos que Nullable<T> en una caja Nullable<T> . Encajonan en una caja T o una referencia nula.
  • Un método implementado por un tipo de valor S se implementa como si tuviera un argumento ref S invisible; Así es como se pasa esto.
  • Un método implementado por un tipo de referencia C se implementa como si hubiera un argumento C invisible; Así es como se pasa esto.
  • El caso interesante es un método virtual definido en una clase base de referencia y reemplazado por una estructura que hereda de la clase base.

Ahora tienes suficiente información para deducir lo que pasa. GetHashCode es virtual y está anulado por Nullable<T> modo que cuando lo llamas, lo llamas como si hubiera un ref Nullable<T> invisible para this . No pasa el boxeo.

GetType no es virtual y, por lo tanto, no se puede anular y se define en el object . Por lo tanto, espera un object para this . Cuando se llama a un Nullable<T> el receptor debe estar encuadrado, y por lo tanto puede encasillar en nulo, y por lo tanto puede lanzar.

Si ((object)x).GetHashCode() entonces ((object)x).GetHashCode() una excepción.


Parece que GetHashCode tiene un cheque nulo. (Usado JetBrains para ver la definición)

public override int GetHashCode() { if (!this.hasValue) return 0; return this.value.GetHashCode(); }