c#装箱与拆箱

在c#语言中有两种类型,分别是引用类型和值类型,由于值类型不在托管堆中分配、不被垃圾回收机制印象、同样也不需要引用(指针)来引用,因此可能看上去,值类型要比引用类型更加轻巧,但是有的时候,我们所需要的是一个引用,而不是值类型,如下例

void Start()
    {
        ArrayList array = new ArrayList();
        Vector3 vector;
        for(int i = 0;i< 3;i++)
        {
            vector.x = 1;
            vector.y = 2;
            vector.z = 3;
            array.Add(vector);
        }
    }

如果查看ArrList类的add方法可以发现add方法的参数是一个引用类型的变量,但是显然vector是一个值类型的变量,而不是引用,因此在这种时候,必须将值类型转换为引用类型,这就涉及到了装箱

装箱步骤

1.在托管堆中分配内存。需要注意的是,由于是将值类型进行引用类型话,因此在分配内存空间除了值类型需要的各个字段所需的内存之外,还要再加上托管堆说有对象都有的两个额外成员(类型对象和同步索引块)所需的内存
2.将值类型的字段赋值到新分配的堆内存中
3.返回对象地址,即对象引用,至此,值类型变成引用类型

结合上面的例子可以看出,在装箱过程中,当C#编译器检测到array.add,这行代码是向要求引用类型的方法传递值类型时,会自动生成代码对V进行装箱,在运行时,当前v的字段中储存的值会被赋值到新分配的对象中去,以装箱的Vector3对象(认为时引用类型)的地址会被返回给add方法,而装箱后的对象会一直存在于托管堆中,直至被垃圾回收。

拆箱,如下

Vector3 vector3 = vector[0];

这行便是执行了拆箱操作,需要注意的是,在拆箱中必须要告诉编译器,要拆成什么类型。具体过程如下

1.获取已经装箱的Vector3对象中各个字段的地址,这个过程便是所说的拆箱
2.将已经装箱的Vector3对象中各个字段的值从托管堆上复制到线程栈的新的值类型vector3上去

注意不要把拆箱当作装箱的逆过程,拆箱并不涉及到复制的过程。而是复制过程,相比于装箱,拆箱的代价要小得多,而且拆箱的目标类型一定要是未装箱的值类型;由于装箱和拆箱、复制会堆程序的速度和内存空间产生不利的影响,甚至可能会由于频繁的操作托管堆导致增加GC次数,因此,装箱拆箱次数越少越好,日常开发中一般使用List< T >而不是ArrayList这种会触发装箱机制的类型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值