【面试题研究3】c#中装箱和拆箱的概念

来源:互联网 发布:php和mysql web 编辑:程序博客网 时间:2024/06/05 15:44
C#中的数据分为值类型和引用类型两种

值类型
  直接包含值,不能为null,可以在栈上分配。复制时直接复制一份内存
   除string外的所有基本类型,以及用struct定义的结构体

引用类型
变量指向数据存储的位置,在堆上分配,复制时传递的是地址,多个变量可以引用同一个对象。

装箱就是将值类型转换为对应的引用类型,
步骤:
1.在堆上分配内存,用于存放值类型的数据以及少许额外开销
2.内存复制,值类型数据拷贝到堆上
3.更新对象或接口引用,指向堆上的位置

拆箱则是相反的操作,根据定义,CIL指令unbox只是对堆上的数据进行解引用,并不包括从堆复制到栈的动作,
但在C#语言中,大多数时候都会在拆箱后发生一次内存拷贝。

频繁的装箱和拆箱会引起较大的性能开销,因此在一些循环中尤其需要注意这一点。
以下为装箱、拆箱的例子
 int num = 10; object obj = num; int num2 = (int)obj;

IL反汇编器查看如下:
  .maxstack  1  .locals init ([0] int32 num,           [1] object obj,           [2] int32 num2)  IL_0000:  nop  IL_0001:  ldc.i4.s   10  IL_0003:  stloc.0  IL_0004:  ldloc.0  IL_0005:  box        [mscorlib]System.Int32  IL_000a:  stloc.1  IL_000b:  ldloc.1  IL_000c:  unbox.any  [mscorlib]System.Int32  IL_0011:  stloc.2  IL_0012:  ret