我无法找到以下问题的答案:
object o = 10; // Box
int i = (int)o; // Unbox
很明显,但以下内容尚不清楚
bool isInt = o is int; // Is the unbox here or not?
答案 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
关键字刚刚获得了新角色。