知識點:引用類型、值類型、裝箱、拆箱
CLR支持兩種類型:引用類型和值類型。引用類型在堆上分配內存,值類型在線程棧上分配內存。值類型與引用類型如下所示:
值類型對象有兩種表示形式:未裝箱和已裝箱。將一個值類型的變量付給另一個值類型變量,會執行一次逐字段的復制。
裝箱:將一個值類型轉換為一個引用類型稱為裝箱。裝箱會發生如下操作:
1、在托管堆中分配好內存。分配的內存大小等於值類型各個字段需要的內存大小之和加上類型對象指針和同步塊索引需要的內存量。
2、值類型的字段復制到新分配的堆內存。
3、返回對象的地址。
拆箱:將一個引用類型轉換為值類型,首先值類型的內存分配在線程棧中,而引用類型的內存分配在托管堆中,所以需要把引用類型中的所有字段都復制到線程棧中。CLR通過兩個步驟來完成這個復制操作。
1、獲取已裝箱的對象中的各個字段的地址。這個過程稱為拆箱。
2、將這些字段包含的值從托管堆復制到線程棧中。
通過下面例子來深入理解裝箱和拆箱:
internal struct Point { private int _x, _y; public Point(int x = 0, int y = 0) { _x = x; _y = y; } public void Change(int x = 0, int y = 0) { _x = x; _y = y; } public override string ToString() { return string.Format("{0},{1}",_x,_y); } } class Program { static void Main(string[] args) { Point p = new Point(x:1,y:1); Console.WriteLine(p); p.Change(x:2,y:2); Console.WriteLine(p); Object o = p; Console.WriteLine(o); ((Point)o).Change(x:3,y:3); //這個執行結果是多少?為什么? Console.WriteLine(o); Console.ReadLine(); } }