c# .net reflection nullable gettype

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í:

¿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.