【C#】裝箱與拆箱
阿新 • • 發佈:2019-01-09
在生活中,我們都喜歡吃水果。大家都知道水果不但為我們提供豐富的膳食纖維,還有維生素及其它營養。例如:吃草莓培養耐心補充維生素,吃香蕉保持快樂心情,吃葡萄增強免疫抗衰老,吃梨幫助器官排毒等等,所有我們經常去買水果,而一般水果都是裝在箱子裡,廠商把水果裝箱賣給經銷商,經銷商在拆箱賣給我們。這就是生活中的裝箱和拆箱,然而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一個新的物件,當量特別大是肯定會大大影響程式的效率。五、小結
在應用中,我們應該儘量避免裝箱操作。瞭解了裝箱和拆箱的操作,我們可以清楚的明白:裝箱操作會導致資料在堆和棧上進行拷貝,頻繁的裝箱操作會效能損失。而相比而言拆箱過程對效能損耗還是比較小的。