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 cajaNullable<T>. Encajonan en una cajaTo una referencia nula. - Un método implementado por un tipo de valor
Sse implementa como si tuviera un argumentoref Sinvisible; Así es como se pasa esto. - Un método implementado por un tipo de referencia
Cse implementa como si hubiera un argumentoCinvisible; 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();
}