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

Via*_*ukh 13 .net c#

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

object o = 10; // Box
int i = (int)o; // Unbox
Run Code Online (Sandbox Code Playgroud)

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

bool isInt = o is int; // Is the unbox here or not?
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 27

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

检查的一种方法是编译代码并使用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
Run Code Online (Sandbox Code Playgroud)

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

  • @ViacheslavSmityukh:是的.不要忘记,确实有一个涉及的对象,有一个类型.无论值是否为盒装值类型值,检查该类型基本上是相同的操作. (3认同)
  • 那么CLR可以在不拆箱的情况下检查类型吗? (2认同)
  • @JonSkeet你能否将这个评论编辑成答案,我认为解释*为什么*,而不仅仅通过IL证明是特别有价值的. (2认同)

Jon*_*nna 5

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

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

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

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

因此,测试类型不能要求拆箱.