什么是使用Nullable.GetUnderlyingType,如果typeof(int?)是Int32?

时间:2010-12-23 10:56:07

标签: c# nullable

为什么typeof int?Int32

int? x = 1;
Console.WriteLine(x.GetType().Name);

如果可以,那么Nullable.GetUnderlyingType使用了什么?

5 个答案:

答案 0 :(得分:23)

调用GetType()框来表示您的变量。 CLR有一个特殊规则,Nullable<T>被装箱到T。因此x.GetType将返回Int32而不是Nullable<Int32>

int? x = 1;
x.GetType() //Int32
typeof(int?) //Nullable<Int32>

由于包含Nullable的{​​{1}}将被装箱到null,以下内容将引发异常:

null

引用MSDN on Boxing Nullable Types

  

如果对象为非null,则仅基于可空类型的对象进行装箱。如果int? x = null; x.GetType() //throws NullReferenceException HasValue,则将对象引用分配给false而不是装箱

     

如果对象为非null - 如果nullHasValue - 则会发生装箱,但只有可以为空的对象所基于的基础类型被装箱。装箱非空可空值类型会为值类型本身添加框,而不是包装值类型的true

答案 1 :(得分:11)

这个例子有点混淆,因为:

int? x = 1;

像您期望的那样创建Nullable<int>;但是:

Type tupe = x.GetType();

是对object上的非虚方法的调用,它不会(也不能)被覆盖 - 因此这是装箱操作;并且Nullable<T>有特殊的拳击规则:

  • 如果它为空,则会显示为null
  • 如果有值,将被装箱并返回

int? x = 1;
int y = 1;

完全同样的事情。

因此,您将typeof(int)传递给GetUnderlyingType

这有助于何时使用反射的更具说明性的示例:

class Foo {
    public int? Bar {get;set;}
}
...
Type type = typeof(Foo); // usually indirectly
foreach(var prop in type.GetProperties()) {
     Type propType = prop.PropertyType,
          nullType = Nullable.GetUnderlyingType(propType);

     if(nullType != null) {
         // special code for handling Nullable<T> properties;
         // note nullType now holds the T
     } else {
         // code for handling other properties
     }
}

答案 2 :(得分:4)

当你不知道它的Int32

实施例

    public Type GetNullableUnderlyingType<T>(Nullable<T> obj) 
        where T : struct
    {
        return Nullable.GetUnderlyingType(typeof(Nullable<T>));
    }

在这里,您可以传递任何Nullable对象并让它返回它的基础类型。

答案 3 :(得分:1)

当你写int?时,就像你写了Nullable<int>一样。我想这就是你要找的那种。

答案 4 :(得分:1)

主要用于处理泛型方法:: e.g。

public static void SomeMethod<T>(T argument)
{
     if(Nullable.GetUnderlyingType(typeof(T) != null)
     {
             /* special case for nullable code go here */
     }
     else
     {
            /* Do something else T isn't nullable */
     }
}

知道这一点非常重要,因为某些非常便宜的东西在可空的东西上可能非常昂贵。例如,if(argument == null)通常超级便宜,但是当在Nullable<T>上的通用方法中完成时,强制将argument打包以获得空引用。你最好的选择是使用EqualityComparer<T>.Default,这将减慢其他一切,但让可以为空的人不受影响。