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

Mub*_*han 13 c# nullable

为什么是typeof int?一个Int32

int? x = 1;
Console.WriteLine(x.GetType().Name);
Run Code Online (Sandbox Code Playgroud)

如果没问题那么有什么用Nullable.GetUnderlyingType

Cod*_*aos 23

调用GetType()你的变量框.CLR有一个特殊的规则,Nullable<T>可以装箱T.所以x.GetType将返回Int32而不是Nullable<Int32>.

int? x = 1;
x.GetType() //Int32
typeof(int?) //Nullable<Int32>
Run Code Online (Sandbox Code Playgroud)

由于Nullable包含null将被装箱到null以下将抛出异常:

int? x = null;
x.GetType() //throws NullReferenceException
Run Code Online (Sandbox Code Playgroud)

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

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

如果对象是非null - 如果HasValuetrue- 则发生装箱,但只有可以为空的对象所基于的底层类型被装箱.装箱一个非null的可空值类型框表示值类型本身,而不是System.Nullable<T>包装值类型.


Mar*_*ell 11

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

int? x = 1;
Run Code Online (Sandbox Code Playgroud)

创造出Nullable<int>你期望的样子; 然而:

Type tupe = x.GetType();
Run Code Online (Sandbox Code Playgroud)

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

  • 如果它是空的,它就是盒子 null
  • 如果它有值,则将装箱并返回

int? x = 1;
int y = 1;
Run Code Online (Sandbox Code Playgroud)

盒子完全一样的东西.

因此,要传递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
     }
}
Run Code Online (Sandbox Code Playgroud)

  • `GetUnderlingType` - 我当天最喜欢的拼写错误.还有,`tupe`. (2认同)