c# - ¿Por qué GetType devuelve System.Int32 en lugar de Nullable<Int32>?
.net reflection (4)
No puedes box un nulo.
Podrías 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]
Esta pregunta ya tiene una respuesta aquí:
- Tipo anulable no es un tipo que admite nulo 4 respuestas
¿Por qué el resultado de este fragmento es System.Int32
lugar de Nullable<Int32>
?
int? x = 5;
Console.WriteLine(x.GetType());
Porque el tipo de "5" es int.
Si desea detectar si un tipo es anulable, y el tipo subyacente, use 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;
}
GetType()
es un método de object
.
Para llamarlo, la Nullable<T>
debe estar encuadrada.
Puedes ver esto 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
Los tipos anulables son tratados especialmente por CLR; es imposible tener una instancia en caja de un tipo que admite nulos.
En cambio, el boxeo de un tipo anulable dará como resultado una referencia nula (si HasValue
es falso), o el valor HasValue
(si hay un valor).
Por lo tanto, la instrucción de box System.Nullable<System.Int32>
da como resultado un Int32
Nullable<Int32>
, no un Nullable<Int32>
.
Por lo tanto, es imposible que GetType()
devuelva Nullable<T>
alguna vez .
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 de tiempo de compilación: System.Nullable`1 [System.Int32]
Tipo de tiempo de ejecución: System.Int32
GetType()
no es virtual y, por lo tanto, se define solo en el object
. Como tal, para realizar la llamada, el Nullable<Int32>
primero debe estar encuadrado. Sin embargo, Nullables tiene reglas especiales de boxeo, por lo que solo el valor Int32
está encuadrado, y ese es el tipo informado.