我得到的这个比较符合预期,false
等于
bool eq = typeof(int?).Equals(typeof(int));
现在我有了这段代码
List<object> items = new List<object>() { (int?)123 };
int result = items.OfType<int>().FirstOrDefault();
但这将返回123
-无论如何该值的类型为int?
怎么可能?
答案 0 :(得分:59)
可空类型具有特殊的“装箱”规则;根据您的代码,“装箱”是将值类型视为object
时。与常规值类型不同,将可为空的值类型或装箱为null
(常规为null
,没有类型)或不可为空 strong>类型(T
中的T?
)。因此:int?
被装箱为int
,而不是int?
。然后,在其上使用OfType<int>()
时,将获得所有int
的值,即:您传入的单个值,因为它的是类型为{{1 }}。
答案 1 :(得分:9)
以下规则将可空值类型装箱
HasValue
返回false
,则产生空引用。 HasValue
返回true
,则基础值类型为T
的值是
装箱,而不是可以为null的实例。在您的示例中,遵循第二条规则,因为您拥有价值,例如
var i = (object)(int?)123;
答案 2 :(得分:4)
有点晚了,但是除了Marc回答您的问题之外,我还想提供一些有关CLR中Nullable值类型的其他信息。
CLR内置支持可空值类型。此 特殊支持 用于装箱,取消装箱,调用GetType
,调用接口方法 。 / p>
例如,让我们检查GetType()
:
Int32? x = 5;
Console.WriteLine(x.GetType());
您认为它将打印到控制台吗?
System.Nullable<Int32
?不是,结果是System.Int32
。
或者,让我们检查一下您在问题中指出的拳击手:
Int32? n =5;
Object o = n;
Console.WriteLine("o's type={0}", o.GetType()); // "System.Int32"
规则是:
CLR将Nullable实例装箱时,它会检查它是否 为null,如果是,则CLR实际上不会装箱任何东西,并且null为 回到。如果可为空的实例不为null,则CLR将采用 值从可空实例中取出并装箱。换句话说, 值为5的Nullable被装箱到boxed-Int32中,其中 值为5。
最后,我想解释一下CLR如何为从Nullable Types调用接口方法添加特殊支持。 让我们来看看:
Int32? n = 5;
Int32 result = ((IComparable) n).CompareTo(5); // Compiles & runs OK
Console.WriteLine(result); // 0
在前面的代码中,我将Nullable<Int32>
的n强制转换为IComparable<Int32>
的接口
类型。但是,Nullable<T>
类型未将IComparable<Int32>
接口实现为
Int32
可以。 C#编译器允许此代码始终进行编译。