¿Por qué la salida de este fragmento System.Int32
en lugar de Nullable<Int32>
?¿Por qué GetType devuelve System.Int32 en lugar de Nullable <Int32>?
int? x = 5;
Console.WriteLine(x.GetType());
¿Por qué la salida de este fragmento System.Int32
en lugar de Nullable<Int32>
?¿Por qué GetType devuelve System.Int32 en lugar de Nullable <Int32>?
int? x = 5;
Console.WriteLine(x.GetType());
GetType()
es un método de object
.
Para invocarlo, la estructura Nullable<T>
debe estar enmarcada.
Esto se puede ver en el código IL:
//int? x = 5;
IL_0000: ldloca.s 00
IL_0002: ldc.i4.5
IL_0003: call System.Nullable<System.Int32>..ctor
//Console.WriteLine(x.GetType());
IL_0008: ldloc.0
IL_0009: box System.Nullable<System.Int32>
IL_000E: callvirt System.Object.GetType
IL_0013: call System.Console.WriteLine
tipos anulables se tratan de forma especial por CLR; es imposible tener una instancia en caja de un tipo que admite nulos.
En su lugar, el boxeo de tipo anulable dará como resultado una referencia nula (si HasValue
es falso), o el valor encuadrado (si hay un valor).
Por lo tanto, la instrucción box System.Nullable<System.Int32>
da como resultado Int32
en caja, no en caja Nullable<Int32>
.
Por lo tanto, es imposible para GetType()
a alguna vez return Nullable<T>
.
Para ver esto más claramente, mira el siguiente código:
static void Main()
{
int? x = 5;
PrintType(x);
}
static void PrintType<T>(T val) {
Console.WriteLine("Compile-time type: " + typeof(T));
Console.WriteLine("Run-time type: " + val.GetType());
}
Esto imprime
tipo en tiempo de compilación: System.Nullable`1 [System.Int32]
Run- tipo de hora: System.Int32
No se puede box un anulable.
se podría hacer algo como esto:
public static Type GetCompilerType<T>(this T @object)
{
return typeof (T);
}
int? x = 5;
Console.WriteLine(x.GetCompilerType());
// prints:
// System.Nullable`1[System.Int32]
GetType()
no es virtual, y por lo tanto se define sólo en object
. Como tal, para realizar la llamada, primero se debe incluir el Nullable<Int32>
. Nullables tiene reglas especiales de boxeo, por lo que solo el valor Int32
está encuadrado, y ese es el tipo informado.
¿Hay alguna razón particular por la que Nullable
@supercat No estoy seguro de estar calificado para responder esa pregunta.Una cosa que diré es que las estructuras que se pueden anular son tontas de muchas maneras, debido al hecho de que básicamente se agregaron después del hecho, en lugar de incorporarse al lenguaje desde el principio. El punto general aún se cumple, supongo, ya que necesita colocar una variable 'int' para llamar a' GetType() 'también. Como siempre se van a cargar los tipos en los que esto debería importar, es posible que se trate de una concesión de consistencia de espacio/documentación. Tal vez Eric Lippert puede arrojar algo más de luz. – dlev
@supercat 'GetType()' no tiene sentido para un tipo 'sellado', porque puede usar' typeof() '. 'Nullable
Porque el tipo de "5" es int.
Si desea detectar si un tipo es anulable, y el tipo subyacente, usar algo como esto:
public static Type GetActualType(Type type, out bool isNullable)
{
Type ult = Nullable.GetUnderlyingType(type);
if (ult != null)
{
isNullable = true;
return ult;
}
isNullable = false;
return type;
}
Eso no es correcto, SLaks. Mire la documentación aquí: http://msdn.microsoft.com/en-us/library/system.nullable.getunderlyingtype.aspx que dice: "Valor de retorno Tipo: System.Type El argumento de tipo del parámetro nullableType, si el parámetro nullableType es un tipo genérico anulable cerrado; de lo contrario, nulo. " –
Tienes razón; Yo extraví. Sin embargo, esto no responde la pregunta. 'x' ** es ** un' int? '. – SLaks
Y "5" es un int. –
Identificador de espera; 'objeto' es una palabra clave – SLaks
@slaks, gracias ... se olvidó de arreglar eso. –