首页 > 代码库 > 装箱和拆箱

装箱和拆箱

装箱和拆箱

所谓的装箱和拆箱呢,也就是值类型和引用类型之间的转换.

  而为什么会有转换呢?是因为这两个不在同一个环境,一个在线程栈,一个在托管堆

什么是值类型

  值类型也就是一般不包含指向实例的指针,一般用struct来标志,反之就是引用类型(class)

装箱

  和现实中联系起来,也就是将某个东西进行打包,装饰.具体步骤如下,

    >计算需要装箱的值类型结构的大小,然后加上类型对象指针同步索引块的大小,并在托管堆上分配内存

    >然后将值类型逐位进行复制

    >然后返回装箱对象的地址

  就这样一个值类型就被装箱成了引用类型

拆箱

  具体步骤:

    >值类型获取装箱类型的各个字段的引用

    >逐位进行复制

struct(结构)

//这就是一个简单的结构   
 struct d1
    {
        public int i;
    }

  那么这个结构是用来干什么的呢?我们不是有了一个引用类型class?

    当然是因为class有不足之处才有了结构,当然这只是一个方面

      >由于引用对象生存在托管堆上,每次你new一个实例,就会分配内存,而struct是直接赋值

      >每个堆对象都会有附加的两个对象,  类型对象指针和同步索引块(这也是为什么值类型不能lock的根本原因)

      >为了对应C语言的union

        为了可以控制struct字段在内存中的位置,C#提供了[StructLayout()],用这个属性来标识CLR如何排布字段

          >LayoutKind.Auto  CLR自动分配

          >LayoutKind.Explicit  可以使用 [FieldOffset()]进行分配

          >LayoutKind.Sequential  可以是不连续

       然后我们来看一个例子

    [StructLayout(LayoutKind.Explicit)]
struct dd
    {
//联合成员0-0
        [FieldOffset(0)]
      public  int i;
        [FieldOffset(0)]
     public   int j;
    }

执行代码:

        static void Main(string[] args)
        {
            dd d;
            d.i = 1;
            d.j = 2;
            Console.WriteLine("i:\t"+d.i.ToString());
            Console.WriteLine("j:\t" + d.j.ToString());
            Console.Read();
        }

结果图:

 技术分享

 

装箱和拆箱