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

为什么是typeof int? 一个Int32

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

如果可以,那么Nullable.GetUnderlyingType的用途是什么?

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

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

由于包含nullNullable将被装箱为null因此以下内容将引发exception:

 int? x = null; x.GetType() //throws NullReferenceException 

在拳击可空类型上引用MSDN :

如果对象为非null,则仅基于可空类型的对象进行装箱。 如果HasValuefalse ,则将对象引用分配为null而不是装箱

如果对象是非null – 如果HasValuetrue – 则发生装箱,但只有可以为空的对象所基于的基础类型被装箱。 装箱非空可空值类型框表示值类型本身,而不是包装值类型的System.Nullable

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

 int? x = 1; 

像你期望的那样创建一个Nullable ; 然而:

 Type tupe = x.GetType(); 

是对object的非虚方法的object ,它不被(也不能被)覆盖 – 因此这是一个装箱操作; 和Nullable有特殊的拳击规则:

  • 如果它是空的,则为空
  • 如果它有值,则将装箱并返回

 int? x = 1; int y = 1; 

盒子完全一样的东西。

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

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

 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 properties; // note nullType now holds the T } else { // code for handling other properties } } 

当你不知道它的Int32

例:

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

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

当你写int? 就像你写了Nullable 。 我想这就是你要找的那种。

主要用于处理generics方法::例如

 public static void SomeMethod(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上的generics方法中完成时,强制将argument为获取空引用。 你最好的选择是使用EqualityComparer.Default ,它会减慢其他所有内容的速度,但是可以使nullable不受影响。