15

我找不到以下问题的答案:

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

很清楚,但以下不清楚

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

3 回答 3

29

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

一种检查方法是编译代码并使用 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- 不需要拆箱。

于 2012-08-31T20:28:06.860 回答
5

它不仅不需要拆箱,从逻辑上讲,它也不需要。

拆箱可以成功也可以失败,这取决于对象是否真的包含我们要尝试拆箱的类型的值。

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

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

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

于 2012-08-31T23:18:04.683 回答
-1

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

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

显然,这与原始帖子的情况不同,原始帖子中的值纯粹是被测试的,因为当is用作模式时,您实际上是在分配值。因此在这种情况下需要拆箱。

需要明确的是 - 原始o is int案例没有任何改变 - 根据旧答案,那里不会发生拆箱。is关键字刚刚获得了新的作用。

于 2017-09-03T16:29:07.807 回答