装箱:值类型转换为引用类型;
拆箱:引用类型转换为值类型;
由于C#中所有的数据类型都是由基类System.Object继承而来的,所以值类型和引用类型的值可以通过显式
(或隐式)操作相互转换,而这转换过程也就是装箱(boxing)和拆箱(unboxing)过程。
装箱 是值类型到 object 类型或到此值类型所实现的任何接口类型的隐式转换。对值类型装箱会在堆中分配一
个对象实例,并将该值复制到新的对象中。
拆箱 是从 object 类型到值类型或从接口类型到实现该接口的值类型的显式转换。
-------------------
为何需要装箱?
一种最普通的场景是,调用一个含类型为Object的参数的方法,该Object可支持任意为型,以便通用。当你需
要将一个值类型(如Int32)传入时,需要装箱。
另一种用法是,一个非泛型的容器,同样是为了保证通用,而将元素类型定义为Object。于是,要将值类型数据
加入容器时,需要装箱。
装箱的内部操作。
装箱: 对值类型在堆中分配一个对象实例,并将该值复制到新的对象中。按三步进行。
第一步:新分配托管堆内存(大小为值类型实例大小加上一个方法表指针和一个SyncBlockIndex)。
第二步:将值类型的实例字段拷贝到新分配的内存中。
第三步:返回托管堆中新分配对象的地址。这个地址就是一个指向对象的引用了。
拆箱:检查对象实例,确保它是给定值类型的一个装箱值。将该值从实例复制到值类型变量
中。
装箱/拆箱对执行效率的影响(如何优化效率)
装箱时,生成的是全新的引用对象,这会有时间损耗,也就是造成效率降低。 那该如何做呢?
避免装箱的方法:
1、通过重载函数来避免。
2、通过泛型来避免。
凡事并不能绝对,假设你想改造的代码为第三方程序集,你无法更改,那你只能是装箱了
。 对于装箱/拆箱代码的优化,由于C#中对装箱和拆箱都是隐式的,所以,根本的方法是对
代码进行分析,而分析最直接的方式是了解原理结何查看反编译的IL代码。比如:在循环体
中可能存在多余的装箱,你可以简单采用提前装箱方式进行优化。