.NET 中的裝箱與拆箱實現過程

來源:互聯網
上載者:User
先看下面的代碼:

int tempi = 1; object o = tempi; double tempd = (double) o;

編譯時間可以通過,但運行時卻報如下錯誤:
System.InvalidCastException: 指定的轉換無效。

這是因為,當對一個對象進行拆箱時,轉型的結果必須是它原來未裝箱的類型。此處必須先轉換為int類型,才能再轉換為double類型。其正確格式如下:

int tempi = 32; object o = tempi; double tempd = (double)(int) o;

在.NET架構中,裝箱(boxing)通常由以下三步組成:
1.從託管堆中為新產生的參考型別對象分配記憶體。分配的記憶體大小為被裝箱的實值型別執行個體本身的大小,再加上為新產生的參考型別添加的一個方法表指標和一個SyncBlockIndex。
2.將實值型別執行個體的欄位拷貝到託管堆上新指派至的記憶體中。
3.返回託管堆中新指派至的地址。這樣實值型別執行個體也變成了一個參考型別對象。

而拆箱(unboxing)過程則如下:
1.如果要拆箱的對象為null,將會拋出一個NullReferenceException異常。
2.如果該引用指向的對象不是一個期望的實值型別的已裝箱對象,則拆箱失敗,並拋出一個InvalidCastException異常(如本文剛開始的部分)。
3.一個指向包含在已經裝箱對象中實值型別部分的指標被返回。該指標指向的實值型別對於參考型別對象通常所具有的附加成員(即一個方法表指標和一個SyncBlockIndex)一無所知。實際上,該指標指向的是已經裝箱對象中的未裝箱部分(Microsoft.NET 架構程式設計<修訂版>)。

對於第3點,可以使用上面的例子來協助理解。首先定義實值型別變數tempi,它在記憶體中佔用4個位元組,裝箱之後,其變成引用對象的同時,增加了一個方法表指標和一個SyncBlockIndex。對於參考型別而言,只需要傳一個“參考型別”的地址,就可以得到其值、方法表指標和SyncBlockIndex。在拆箱時,傳遞的是其“值”的地址(未裝箱的部分),即一個“int(Int32)類型”的地址(引用),它只允許讀4個位元組。而double類型是8個位元組,因此隱式的轉換是會報錯的,需要先將其轉換成int類型後,才能再轉換為double類型。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.