Arp*_*wal 5 c# boxing unboxing
我明白拳击是什么.值类型被装箱到对象/引用类型,然后作为对象存储在托管堆上.但是我不能通过拆箱来解决问题.
取消装箱会将对象/引用类型转换回值类型
int i = 123; // A value type
object box = i; // Boxing
int j = (int)box; // Unboxing
Run Code Online (Sandbox Code Playgroud)
好的.但是,如果我尝试将值类型拆分为另一个值类型,例如,在上面的示例中,它会抛出InvalidCastException
long d = (long)box;
Run Code Online (Sandbox Code Playgroud)
它让我有一个想法,可能是运行时隐式知道"box"对象中框内的实际TYPE值类型.如果我是对的,我想知道这种类型信息的存储位置.
编辑:
因为int可以隐式转换为long.这让我很困惑.
int i = 123;
long lng = i;
Run Code Online (Sandbox Code Playgroud)
非常好,因为它没有涉及拳击/拆箱.
当一个值被装箱时,它获得一个对象标题.从System.Object派生的任何类型的类型.该标头后面的值.标题包含两个字段,一个是"syncblk",它有各种用途,超出了问题的范围.第二个字段描述了对象的类型.
那就是你要问的那个.它在文献中有各种名称,最常见的是"类型句柄"或"方法表指针".后者是最准确的描述,它是指向CLR在加载类型时跟踪的信息的指针.许多框架功能都依赖于它.Object.GetType()当然.代码中的任何强制转换以及is和as运算符都使用它.这些演员是安全的,所以你不能把狗变成猫,类型手柄提供这种保证.盒装int的方法表指针指向System.Int32的方法表
在仿制药推出之前,拳击在.NET 1.x中很常见.所有常见的集合类型都存储了对象而不是T.因此,将一个元素放入集合中需要(隐式)装箱,再次将其取出需要使用强制转换显式取消装箱.
为了提高效率,抖动非常重要,不需要考虑是否需要进行转换.因为这需要更多的工作.因此,C#语言包含了对另一种类型进行拆箱非法的规则.现在需要的只是检查类型句柄以确保它是预期类型.抖动直接将方法表指针与您案例中System.Int32的指针进行比较.并且可以直接复制对象中嵌入的值,而无需任何转换问题.非常快,尽可能快,这可以通过内联机器代码完成,无需任何CLR调用.
这条规则特定于C#,VB.NET没有它.这两种语言之间的典型权衡,C#的重点是速度,方便VB.NET.当取消装箱不是问题时转换为另一种类型,所有简单的值类型都实现IConvertible.您可以使用Convert helper类在代码中明确地编写它:
int i = 123; // A value type
object box = i; // Boxing
long j = Convert.ToInt64(box); // Conversion + unboxing
Run Code Online (Sandbox Code Playgroud)
这与VB.NET编译器自动生成的代码非常相似.