输入int吗? vs类型int

时间:2019-03-27 08:27:06

标签: c# casting

我得到的这个比较符合预期,false等于

bool eq = typeof(int?).Equals(typeof(int));

现在我有了这段代码

List<object> items = new List<object>() { (int?)123 };
int result = items.OfType<int>().FirstOrDefault();

但这将返回123-无论如何该值的类型为int?

怎么可能?

3 个答案:

答案 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#编译器允许此代码始终进行编译。