1. 程式人生 > >裝箱(boxing)和拆箱(unboxing) [轉]

裝箱(boxing)和拆箱(unboxing) [轉]

1.  裝箱和拆箱

裝箱 就是把“值型別”轉換成“引用型別”;

拆箱 就是把“引用型別”轉換成“值型別”;

首先,我們要弄明白為什麼需要裝箱和拆箱。C#的所有型別,包括int、boo等,都繼承自System.Object,但是卻又有值型別和引用型別之分。這時你要問,int是繼承自object型別的,object是引用型別,那為何int不是引用型別而是值型別的呢?這就涉及到裝箱和拆箱的概念了。

         我們知道物件是建立在堆上的,它的建立和銷燬必然帶來額外的CPU和記憶體消耗。如果將int,boo等微小而常用的資料型別都放在堆上建立和銷燬,語言的效能將會被極大的限制,有時甚至是無法忍受的。C#將值型別和引用型別分開,值型別直接在棧中被建立,超過作用域後直接銷燬。

當需要值型別成為物件時,使用裝箱操作,讓值型別變為一個引用型別的物件。這樣,我們就可以使用object作為通用的介面統一語言內的一切型別。

        拆箱 在MSDN官方文件裡用的是 取消裝箱。事實上拆箱是裝箱的逆操作,也就是說我們只對裝過箱的引用型別(通常是object物件)進行拆箱操作。單純拆箱操作的後果無法設想的。

        裝箱和拆箱是C#的核心概念,C#利用其完成型別系統的統一。有了裝箱,任何型別的值都可以視為一個物件。CLR在裝箱時是將值型別包裝到System.Object的內部,再將其儲存到託管堆上。拆箱是從物件中提取值型別。裝箱是隱式的而拆箱是顯示的。

//裝箱 boxing
int i = 3 ;  //分配在棧上
object o = i ;//隱式裝箱操作,int i 在堆上
object b = (object)i ; //顯示裝箱操作
//拆箱 unboxing
int j = (int) o ;//顯示拆箱(將物件o拆箱為int型別)
 
int k = b ;//error!!, 不能隱式拆箱

拆箱 的操作包括

1,檢查物件例項,以卻確保它是給定值型別的裝箱值。

2,將該值從例項複製到值型別變數中。

 下面來看看這個例子:

int i=0;
System.Object obj=i;
Console.WriteLine
(i+","+(int)obj);


其中共發生了3次裝箱和一次拆箱!^_^,看出來了吧?!
第一次是將i裝箱,第2次是輸出的時候將i轉換成string型別,而string型別為引用型別,即又是裝箱,第三次裝箱就是(int)obj的轉換成string型別,裝箱!
拆箱就是(int)obj,將obj拆箱!!