为什么这个片段的输出 System.Int32的
而不是可空<的Int32>
诠释? X = 5;
Console.WriteLine(x.GetType());
解决方案
的GetType()
是一个方法对象
。照片
要调用它,在可空< T>
结构必须进行装箱
您可以看到在IL code:
// INT? X = 5;
IL_0000:ldloca.s 00
IL_0002:ldc.i4.5
IL_0003:拨打System.Nullable< System.Int32的> ..男星
//Console.WriteLine(x.GetType());
IL_0008:ldloc.0
IL_0009:箱System.Nullable< System.Int32的>
IL_000E:callvirt System.Object.GetType
IL_0013:打电话的System.Console.WriteLine
可空类型是由CLR特殊处理;它是不可能有一个可空类型的装箱实例。
相反,拳击可空类型将导致空引用(如果 hasValue的
是假的),或装箱值(如果有值)。
因此,中System.Nullable< System.Int32的>
指令导致盒装的Int32
,而不是盒装可空<的Int32>
因此,这是不可能的的GetType()
来的永远的回报可空< T>
。
要看到这更清楚,请看下面的code:
静态无效的主要()
{
诠释? X = 5;
打印类型(X);
}
静态无效的打印类型< T>(T VAL){
Console.WriteLine(编译时类型:+ typeof运算(T));
Console.WriteLine(运行时类型:+ val.GetType());
}
这版画
编译时类型:System.Nullable`1 [System.Int32的] 运行时类型:System.Int32
Why is the output of this snippet System.Int32
instead of Nullable<Int32>
?
int? x = 5;
Console.WriteLine(x.GetType());
解决方案
GetType()
is a method of object
.
To call it, the Nullable<T>
struct must be boxed.
You can see this in the IL code:
//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
Nullable types are treated specially by CLR; it is impossible to have a boxed instance of a nullable type.
Instead, boxing a nullable type will result in a null reference (if HasValue
is false), or the boxed value (if there is a value).
Therefore, the box System.Nullable<System.Int32>
instruction results in a boxed Int32
, not a boxed Nullable<Int32>
.
Therefore, it is impossible for GetType()
to ever return Nullable<T>
.
To see this more clearly, look at the following code:
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());
}
This prints
Compile-time type: System.Nullable`1[System.Int32] Run-time type: System.Int32