为什么typeof int?
为Int32
int? x = 1;
Console.WriteLine(x.GetType().Name);
如果可以,那么Nullable.GetUnderlyingType
使用了什么?
答案 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 - 如果
null
为HasValue
- 则会发生装箱,但只有可以为空的对象所基于的基础类型被装箱。装箱非空可空值类型会为值类型本身添加框,而不是包装值类型的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
,这将减慢其他一切,但让可以为空的人不受影响。