IS运算符是否为unbox值类型?

时间:2012-08-31 20:26:46

标签: c# .net

我无法找到以下问题的答案:

object o = 10; // Box
int i = (int)o; // Unbox

很明显,但以下内容尚不清楚

bool isInt = o is int; // Is the unbox here or not?

3 个答案:

答案 0 :(得分:26)

不,这不是拆箱 - 它只是检查类型是否正确。不要忘记确实有一个物体涉及到一个类型。无论值是否为盒装值类型值,检查该类型基本上是相同的操作。 (对于值类型或任何密封类型,可能存在一些可行的优化,因为没有要考虑的继承,但从根本上它仍然检查对象头的"类型"部分。 )

检查这种方法的一种方法是编译代码并使用ILASM查看IL:

// object o = 10
IL_0000:  ldc.i4.s   10
IL_0002:  box        [mscorlib]System.Int32
IL_0007:  stloc.0

// int i = (int) o;
IL_0008:  ldloc.0
IL_0009:  unbox.any  [mscorlib]System.Int32
IL_000e:  stloc.1

 // bool isInt = o is int
IL_000f:  ldloc.0
IL_0010:  isinst     [mscorlib]System.Int32

所以它使用isinst - 不需要拆箱。

答案 1 :(得分:5)

不仅不需要拆箱,逻辑上也不能。

取消装箱可以成功或失败,具体取决于对象是否真的包含我们要尝试取消装箱的类型的值。

因此,取消装箱需要检查对象是否属于该特定类型。

因此,如果测试需要拆箱的类型,那么由于拆箱需要测试类型,我们将无法取消装箱,直到我们第一次取消装箱...

因此,测试类型不需要拆箱。

答案 2 :(得分:-1)

从C#7开始,is关键字获得了一个新的用例,在模式匹配中作为类型模式。在这种情况下,会发生拆箱,例如:

object o = 10;
if (o is int i) {
   // i is the unboxed value.
}

显然,这与纯粹正在测试的原始帖子的情况不同,就像使用is作为模式一样,实际上是在分配值。因此,在这种情况下需要拆箱。

要明确 - 原始o is int案例没有任何变化 - 根据旧答案,不会发生任何拆箱事件。 is关键字刚刚获得了新角色。