.NET 中的裝箱與拆箱實(shí)現(xiàn)過(guò)程
先看下面的代碼:
int tempi = 1;
object o = tempi;
double tempd = (double) o;
編譯時(shí)可以通過(guò),但運(yùn)行時(shí)卻報(bào)如下錯(cuò)誤:
System.InvalidCastException: 指定的轉(zhuǎn)換無(wú)效。
這是因?yàn)?,?dāng)對(duì)一個(gè)對(duì)象進(jìn)行拆箱時(shí),轉(zhuǎn)型的結(jié)果必須是它原來(lái)未裝箱的類(lèi)型。此處必須先轉(zhuǎn)換為int類(lèi)型,才能再轉(zhuǎn)換為double類(lèi)型。其正確格式如下:
int tempi = 32;
object o = tempi;
double tempd = (double)(int) o;
在.NET框架中,裝箱(boxing)通常由以下三步組成:
1.從托管堆中為新生成的引用類(lèi)型對(duì)象分配內(nèi)存。分配的內(nèi)存大小為被裝箱的值類(lèi)型實(shí)例本身的大小,再加上為新生成的引用類(lèi)型添加的一個(gè)方法表指針和一個(gè)SyncBlockIndex。
2.將值類(lèi)型實(shí)例的字段拷貝到托管堆上新分配對(duì)象的內(nèi)存中。
3.返回托管堆中新分配對(duì)象的地址。這樣值類(lèi)型實(shí)例也變成了一個(gè)引用類(lèi)型對(duì)象。
而拆箱(unboxing)過(guò)程則如下:
1.如果要拆箱的對(duì)象為null,將會(huì)拋出一個(gè)NullReferenceException異常。
2.如果該引用指向的對(duì)象不是一個(gè)期望的值類(lèi)型的已裝箱對(duì)象,則拆箱失敗,并拋出一個(gè)InvalidCastException異常(如本文剛開(kāi)始的部分)。
3.一個(gè)指向包含在已經(jīng)裝箱對(duì)象中值類(lèi)型部分的指針被返回。該指針指向的值類(lèi)型對(duì)于引用類(lèi)型對(duì)象通常所具有的附加成員(即一個(gè)方法表指針和一個(gè)SyncBlockIndex)一無(wú)所知。實(shí)際上,該指針指向的是已經(jīng)裝箱對(duì)象中的未裝箱部分(Microsoft.NET 框架程序設(shè)計(jì)<修訂版>)。
對(duì)于第3點(diǎn),可以使用上面的例子來(lái)幫助理解。首先定義值類(lèi)型變量tempi,它在內(nèi)存中占用4個(gè)字節(jié),裝箱之后,其變成引用對(duì)象的同時(shí),增加了一個(gè)方法表指針和一個(gè)SyncBlockIndex。對(duì)于引用類(lèi)型而言,只需要傳一個(gè)“引用類(lèi)型”的地址,就可以得到其值、方法表指針和SyncBlockIndex。在拆箱時(shí),傳遞的是其“值”的地址(未裝箱的部分),即一個(gè)“int(Int32)類(lèi)型”的地址(引用),它只允許讀4個(gè)字節(jié)。而double類(lèi)型是8個(gè)字節(jié),因此隱式的轉(zhuǎn)換是會(huì)報(bào)錯(cuò)的,需要先將其轉(zhuǎn)換成int類(lèi)型后,才能再轉(zhuǎn)換為double類(lèi)型。
相關(guān)文章
ASP.NET編程獲取網(wǎng)站根目錄方法小結(jié)
這篇文章主要介紹了ASP.NET編程獲取網(wǎng)站根目錄方法,較為詳細(xì)的分析了ASP.NET針對(duì)網(wǎng)站目錄及物理路徑的操作技巧,并給出了實(shí)例予以總結(jié),需要的朋友可以參考下2015-11-11.NET實(shí)現(xiàn)微信公共平臺(tái)上傳下載多媒體文件
這篇文章主要介紹了.NET實(shí)現(xiàn)微信公共平臺(tái)上傳下載多媒體文件的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-07-07Javascript 直接調(diào)用服務(wù)器C#代碼 ASP.NET Ajax實(shí)例
近來(lái)總有一些朋友會(huì)問(wèn)到一些入門(mén)的問(wèn)題,把這些問(wèn)題整理一下,寫(xiě)出來(lái)。在以前的文章里,曾經(jīng)利用純JS編寫(xiě)過(guò)Ajax引擎,在真正開(kāi)發(fā)的時(shí)候,大家都不喜歡以這種低效率的方式開(kāi)發(fā),利用MS Ajax的集成的引擎,可以簡(jiǎn)單不少工作。2010-03-03window.showModalDialog兩次加載問(wèn)題清除緩存方法
window.showModalDialog兩次加載問(wèn)題:你第一次打開(kāi)窗口后,第二次瀏覽器沒(méi)有從服務(wù)器端取數(shù)據(jù),而直接找到了你已經(jīng)下載的文件2013-08-081個(gè)文件如何輕松搞定Asp.net core 3.1動(dòng)態(tài)頁(yè)面轉(zhuǎn)靜態(tài)頁(yè)面
這篇文章主要給大家介紹了關(guān)于如何通過(guò)1個(gè)文件輕松搞定Asp.net core 3.1動(dòng)態(tài)頁(yè)面轉(zhuǎn)靜態(tài)頁(yè)面的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Asp.net core 3.1具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05WPF實(shí)現(xiàn)轉(zhuǎn)圈進(jìn)度條效果
這篇文章主要為大家詳細(xì)介紹了WPF實(shí)現(xiàn)轉(zhuǎn)圈進(jìn)度條效果,如何設(shè)計(jì)自定義的繞圈進(jìn)度條,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05淺談ASP.NET常用數(shù)據(jù)綁定控件優(yōu)劣總結(jié)
這篇文章主要介紹了淺談ASP.NET常用數(shù)據(jù)綁定控件優(yōu)劣總結(jié),以便在實(shí)際的開(kāi)發(fā)中選用合適的控件進(jìn)行數(shù)據(jù)綁定,以提高開(kāi)發(fā)效率。2016-12-12