拳击/拆箱 - 仅值类型? ref.types-铸造?
题
从MSDN,我读到拳击/拆箱用于治疗 价值 类型为对象。但是,当我阅读有关Arraylist的信息时,它也会说它也可以进行拳击。因此,我很困惑,因为ArrayList将价值和参考类型作为对象。另外,以下内容不是术语中的拆箱,而只是铸造?
ArrayList a=new ArrayList();
a.Add(someClass);
someClass x=(someClass)a[0];
解决方案
ArrayList
为价值类型执行拳击,但不能执行参考类型。更确切地说, ArrayList
本身不做拳击 - 编译器可以。例如:
ArrayList list = new ArrayList();
list.Add(5);
有效
ArrayList list = new ArrayList();
object boxed = 5; // Perform boxing from value type type
list.Add(boxed);
您的示例确实只是铸造 - 参考转换,而不是拆箱转换。参考类型值不需要装箱即可存储在 ArrayList
- 这已经是参考。
同样,这是拳击的确如此,而不是特定于 ArrayList
. 。拳击只是一种使用值类型值的方式 真的 想要一个参考...参考必须是对象,因此CLR创建一个对象来包装值类型值,并返回对该包装器的引用(存储该值的“框”)。
其他提示
拳击/拆箱是语言和运行时的功能,而不是 ArrayList
. 。松散地说, 是从/到 Object
类型, ,从那以后 ArrayList
接收 Object
S,您通过的任何值类型都会自动用 box
IL指导。
更具体地说,拳击/拆箱涉及创建或检查新对象,并将值类型的数据从堆栈复制到堆(反之亦然)。它相当昂贵,如果可能的话,您想避免使用它。
在参考类型的情况下,通常没有生成拳击代码;任何 unbox
此外,在参考类型上运行的指令只是被忽略了。
我发现将价值类型视为类型系统之外的价值类型是有用的,但是将每个值类型视为具有源自ValueType的无形相应参考类型(又是从对象派生),该类型本质上是与同一成员的类一样作为foo,但支持往返实际价值类型的延伸。
如果将值类型传递给了对象的导数的代码,则将其施放为适当的无形参考类型;如果将该参考类型的对象分配给值类型的变量,则将被抛弃。
顺便说一句,如果我有我的德鲁特人,将有某种方式指定应使用默认铸造方法以外的其他方法,但不存在此类功能。