1. 程式人生 > >C#之裝箱和拆箱

C#之裝箱和拆箱

簡介:   

     我們都知道,C#中的每一種型別要麼是值型別,要麼是引用型別。所以每個物件要麼是值型別的例項,要麼是引用型別的例項。

     值型別和引用型別之間的轉換稱為裝箱和拆箱。

     裝箱:值型別轉換為引用型別。

     拆箱:引用型別轉換為值型別。

在詳細介紹裝箱和拆箱之前,先總結一下什麼是值型別和引用型別?

值型別、引用型別:

     值型別和引用型別都繼承System.Object,引用型別直接從System.Object繼承,而值型別則繼承其子類,即直接繼承System.ValueType。

值型別:

     

引用型別:

   陣列:(派生於System.Array)陣列的元素,不管是引用型別還是值型別,都儲存在託管堆上;

   類:class(派生於System.Object);

   介面:interface(介面不是一個“東西”,所以不存在派生於何處的問題。);

   委託:delegate(派生於System.Delegate);

   object:(System.Object的別名);

   字串:string(System.String的別名)。

裝箱:

int val = 100; 
object obj = val; 
Console.WriteLine (“物件的值 = {0}", obj); 
這是一個裝箱的過程。

詳細步驟(box)

   1、在堆上分配一個記憶體空間,大小等於需要裝箱的值型別物件的大小加上兩個引用型別物件都擁有的成員:型別物件指標和同步塊引用。

   2、把堆疊上的值型別物件複製到堆上新分配的物件。

   3、返回一個指向堆上新物件的引用,並且儲存到堆疊上被裝箱的那個值型別的物件裡。

注:這個步驟不需要我們自己編寫,任何裝箱的地方,編譯器會自動加上執行以上功能的IL程式碼。

拆箱:

int val = 100; 
object obj = val; 
int num = (int) obj; 
Console.WriteLine ("num: {0}", num); 
這是拆箱的過程,將值型別轉換成引用型別,再由引用型別轉換成值型別的過程。

注:被裝過箱的物件才能被拆箱。

詳細步驟(unbox)

 1、獲取已裝箱的物件的地址

 2、將值從堆上的物件中複製到堆疊上的值變數中

拆裝箱的優缺點:

     每次裝箱需要在堆中new一個新的物件,當量特別大時會影響程式的效率,拆箱過程對效能損耗較小。

總結:

    看C#視訊的時候接觸過裝箱和拆箱,當時不是很理解,最近看.net之美的時候看到這部分終於有點共鳴了,學習真的是一個反覆的過程,需要慢慢吸收。