装箱和拆箱
c#中的数据类型可以分为 值 和 引用。
值 包括byte,short,int,long,float,double,decimal,char,bool,enum,struct,变量直接存储数据,编译器分配内存 ;
引用。string,object,和 class 统称为引用类型。当声明一个类时,只在栈中分配一小片内存用于容纳一个地址,而此时并没有为其分配堆上的内存空间。当使用 new 创建一个类的实例时,分配堆上的空间,并把堆上空间的地址保存到栈上分配的小片空间中。
实际上 值 和 引用 都由基类System.Object
继承而来,因此可以通过装箱和拆箱来相互转换。
装箱:值 -> 对象。
int val = 100;
object obj = val;
对值类型在堆中分配一个对象实例,并将该值复制到新的对象中。按三步进行:
- 首先从托管堆中为新生成的引用对象分配内存(大小为值类型实例大小加上一个方法表指针和一个SyncBlockIndex)。
- 然后将值类型的数据拷贝到刚刚分配的内存中。
- 返回托管堆中新分配对象的地址。这个地址就是一个指向对象的引用了。
可以看出,进行一次装箱要进行分配内存和拷贝数据这两项比较影响性能的操作。