为什么GetType返回System.Int32而不是Nullable ?

为什么这个片段System.Int32的输出而不是Nullable

 int? x = 5; Console.WriteLine(x.GetType()); 

GetType()是一个object的方法。
要调用它,必须将Nullable结构框装箱。

你可以在IL代码中看到这个:

 //int? x = 5; IL_0000: ldloca.s 00 IL_0002: ldc.i4.5 IL_0003: call System.Nullable..ctor //Console.WriteLine(x.GetType()); IL_0008: ldloc.0 IL_0009: box System.Nullable IL_000E: callvirt System.Object.GetType IL_0013: call System.Console.WriteLine 

可空类型由CLR专门处理; 不可能有一个可空类型的盒装实例。
相反,装入可空类型将导致空引用(如果HasValue为false)或盒装值(如果有值)。

因此, box System.Nullable指令产生一个盒装的Int32 ,而不是一个盒装的Nullable

因此, GetType() 不可能返回Nullable

要更清楚地看到这一点,请查看以下代码:

 static void Main() { int? x = 5; PrintType(x); } static void PrintType(T val) { Console.WriteLine("Compile-time type: " + typeof(T)); Console.WriteLine("Run-time type: " + val.GetType()); } 

这打印

编译时类型:System.Nullable`1 [System.Int32]
运行时类型:System.Int32

GetType()不是虚拟的,因此仅在object上定义。 因此,要进行调用,必须首先Nullable 。 Nullables有特殊的装箱规则,因此只有Int32值被装箱,这就是报告的类型。

你不能装空。

你可以这样做:

 public static Type GetCompilerType(this T @object) { return typeof (T); } int? x = 5; Console.WriteLine(x.GetCompilerType()); // prints: // System.Nullable`1[System.Int32] 

因为“5”的类型是int。

如果要检测类型是否可为空,以及基础类型,请使用以下内容:

 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; }