关于Boxing和Unboxing

Posted on 2007-01-20 20:26  Caizhanshu'sBlog  阅读(483)  评论(1编辑  收藏  举报
要了解Boxing和Unboxing的原理,首先我们应该先说说引用类型和值类型,引用类型是总是在托管堆里分配的,C#的New操作符返回的就是对象位于托管堆中的内存地址,而值类型是”轻量级“类型,值实例通常分配在线程栈上(虽然他们也可以被嵌入到引用类型的对象中)。
      Boxing(装箱)是将一个值类型转化成引用类型的过程。值类型分配在托管堆中,不会执行垃圾收集,也没有指向他们的指针,但是很多情况,我们必须获得一个指向值类型实例的引用,例如,我们希望创建一个ArrayList对象保存一个Point结构,看起来如下:
Struct Point
{
   public int x,y;
}
class App
{
   ArrayList a=new ArrayList();
   Point p;
   for(int i=0;i<10;i++)
  {
    p.x=p.y=i;
    a.Add(p);
  }
}
  查看ArrayList的Add方法原形是 public virtual int Add(Object value),在这里加入的是一个引用类型   ,而我们的p是结构值类型,其实在运行的时候,CRL把结构p从线程栈中拷贝一份到托管堆,然后返回托管堆中新对象的地址。
     Unboxing(拆箱),将一个引用类型的实例从托管堆里拷贝一份到线程栈里,如
Point p=(Point)a[0];
    Boxing和Unboxing 不是严格意义上的互反操作,拆箱操作的代价要比装箱的代价小的多,拆箱操作只是获取对象中包含的值类型部分(数据字段)的指针而已,它不会想装箱子那样涉及任何内存的字节的拷贝,然而,紧接着拆箱之后典型的操作往往就是字段拷贝了,这两个操作和起来和装箱操作才是真正的互反操作。
   所以,无论是Boxing还是Unboxing,都会损失一定的性能,如果程序对性能的要求很高的话,应该尽量减少Boxing、Unboxing

Copyright © 2024 Caizhanshu'sBlog
Powered by .NET 8.0 on Kubernetes