1. 程式人生 > >【C#】裝箱與拆箱

【C#】裝箱與拆箱

           在生活中,我們都喜歡吃水果。大家都知道水果不但為我們提供豐富的膳食纖維,還有維生素及其它營養。例如:吃草莓培養耐心補充維生素,吃香蕉保持快樂心情,吃葡萄增強免疫抗衰老,吃梨幫助器官排毒等等,所有我們經常去買水果,而一般水果都是裝在箱子裡,廠商把水果裝箱賣給經銷商,經銷商在拆箱賣給我們。這就是生活中的裝箱和拆箱,然而C#中的又是如何的呢?

  一、概念  

  1、裝箱 : 

         值型別引用型別或到此值型別所實現的任何介面型別的隱式轉換  


程式碼展示:

<span style="font-size:18px;">public class Test
  {
    public static void Main(String[] args)
    {
       int i = 111;
       //將值型別的i裝箱
       //需要注意的是:這裡的裝箱採用的是值的拷貝
       object obj = i;
       //檢驗是否裝箱成功了
       if(obj is int)
       {
         Console.WriteLine("資料已經裝箱!");
       }
       //我們在這裡更改i的值
       i = 222;
       Console.WriteLine("int i現在的值是:{0}",i);
       Console.WriteLine("int i裝箱的值是:{0}",obj);
   }

</span>

 2、  拆箱:

          從引用型別到任意值型別的顯式轉換

 

程式碼展示:

<span style="font-size:18px;">  int i = 10;
   object obj = i;
   int j = (int)obj; </span>

二、為何需要裝箱?(為何要將值型別轉為引用型別?) 

一種最普通的場景是,呼叫一個含型別為Object的引數的方法,該Object可支援任意為型,以便通用。當你需要將一個值型別(如Int32)傳入時,需要裝箱。 
另一種用法是,一個非泛型的容器,同樣是為了保證通用,而將元素型別定義為Object。於是,要將值型別資料加入容器時,需要裝箱。

三、:裝箱/拆箱的內部操作。 

裝箱: 
對值型別在堆中分配一個物件例項,並將該值複製到新的物件中。按三步進行。 
第一步:新分配到堆記憶體。
第二步:將值型別的例項欄位拷貝到新分配的記憶體中。 
第三步:返回託管堆中新分配物件的地址。這個地址就是一個指向物件的引用了。 
拆箱:
檢查物件例項,確保它是給定值型別的一個裝箱值。將該值從例項複製到值型別變數中。 
有書上講,拆箱只是獲取引用物件中指向值型別部分的指標,而內容拷貝則是賦值語句之觸發。我覺得這並不要緊。最關鍵的是檢查物件例項的本質,拆箱和裝箱的型別必需匹配

四、拆箱和裝箱的缺點

裝箱和拆箱雖然滿足了兩隻型別之間的轉換。但是從裝箱的過程中不難看出,每次裝箱時要在堆中new一個新的物件,當量特別大是肯定會大大影響程式的效率。

五、小結

在應用中,我們應該儘量避免裝箱操作。瞭解了裝箱和拆箱的操作,我們可以清楚的明白:裝箱操作會導致資料在堆和棧上進行拷貝,頻繁的裝箱操作會效能損失。而相比而言拆箱過程對效能損耗還是比較小的。