C#类型系统—装箱和拆箱
1 装箱
装箱用于在托管堆中存储值类型。装箱是值类型转换为object类型或由此值类型实现的任何接口类型的隐式转换。调用值类型的GetType()方法时,均会发生装箱。
对值类型在堆中分配一个对象实例,并将该值复制到新的对象中,按三步进行。
①首先从托管堆中为新生成的引用对象分配内存(大小为值类型实例大小加上一个方法表指针和一个SyncBlockIndex)。
②然后将值类型的数据拷贝到刚刚分配的内存中。
③返回托管堆中新分配对象的地址。这个地址就是一个指向对象的引用了。
· 可以看出,进行一次装箱要进行分配内存和拷贝数据这两项比较影响性能的操作。
2 拆箱
拆箱是从object类型到值类型或从接口类型到实现该接口的值类型的显示转换。
操作分为二步。
①首先获取托管堆中属于值类型的那部分字段的地址。此为真正意义的拆箱。
②将引用对象中的值拷贝到位于线程堆栈上的值类型实例中。
相对于装箱,拆箱代价要小的多。严格意义上的拆箱其实就是获取引用的过程,获取的这个引用指向了一个分配在托管堆上的对象中的值,拆箱并不涉及复制过程,即第一步并不影响性能。第二步的拷贝数据的操作则影响性能。