为什么GetType返回System.Int32而不是Nullable <int32>?</int32>

时间:2011-08-03 19:00:04

标签: c# .net reflection nullable gettype

为什么此代码段System.Int32的输出代替Nullable<Int32>

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

4 个答案:

答案 0 :(得分:29)

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

您可以在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

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

因此,box System.Nullable<System.Int32>指令会生成一个装箱Int32,而不是装箱Nullable<Int32>

因此,GetType() 永远无法返回Nullable<T>

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

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

打印

  

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

答案 1 :(得分:8)

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

答案 2 :(得分:4)

你不能box可以为空。

你可以这样做:

public static Type GetCompilerType<T>(this T @object)
{
  return typeof (T);
}

int? x = 5;
Console.WriteLine(x.GetCompilerType());
// prints:
// System.Nullable`1[System.Int32]

答案 3 :(得分:1)

因为“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;
}