显然,JIT编译器可以为第一种情况生成的机器代码效率更高。确实有帮助的一条规则是,只能将对象取消装箱到与装箱值具有相同类型的变量。这使JIT编译器可以生成非常有效的代码,而无需考虑值转换。
将 是
运营商的测试很容易,只要检查对象是不是null,而是预期的类型的,但需要一些机器代码指令。转换也很容易,JIT编译器知道值位在对象中的位置并直接使用它们。没有复制或转换发生,所有机器代码都是内联的,只需要十几条指令。当装箱很普遍时,这在.NET
1.0中必须非常有效。
转换为int?需要做更多的工作。装箱整数的值表示形式与的内存布局不兼容
Nullable<int>。需要进行转换,并且由于可能的装箱枚举类型不同,因此代码很棘手。JIT编译器生成对名为JIT_Unbox_Nullable的CLR帮助器函数的调用,以完成工作。这是任何值类型的通用函数,其中有许多代码可用于检查类型。并复制该值。由于此代码已锁定在mscorwks.dll中,因此难以估算成本,但是可能会有数百条机器代码指令。
Linq OfType()扩展方法还使用 is
运算符和强制类型转换。但是,这是强制转换为通用类型。JIT编译器会生成对辅助函数JIT_Unbox()的调用,该函数可以将类型转换为任意值类型。
Nullable<int>考虑到应该减少工作量,我对此没有很好的解释。我怀疑ngen.exe可能会在这里引起麻烦。



