裝箱與拆箱就是值型別與引用型別的轉換,是值型別和引用型別之間的橋梁。只有值型別才存在裝箱和拆箱,裝箱是隱式的,而拆箱是顯示的。裝箱與拆箱的過程包含了對堆上記憶體的操作,故會消耗效能,裝箱需要比原資料更多的空間,因為它需要生成引用型別的標準配置:型別物件指標和同步塊索引
int i =1;
object o = i;
具體過程
在堆內申請記憶體,記憶體大小為值型別的大小,再加上額外固定空間(型別物件指標和同步塊索引)
將值型別的字段拷貝到新分配的記憶體中
返回新引用物件的記憶體位址(給棧上的引用)
裝箱就是生成圖中除了i = 1變數之外另外兩塊記憶體空間資料的過程
拆箱就是把裝箱後的引用型別轉換為值型別的過程,但是拆箱不是一定成功的,所以存在出現異常的可能
具體過程
int b =
(int
)o;
檢查是否為null,否則丟擲nullreferenceexception異常,檢查例項是否為給定值型別的裝箱值,否則丟擲invalidcastexception異常,最後獲得物件各個成員的位址
建立乙個新的int值型別物件b,並將第一步獲得的值複製到b中
c# 2通過引入泛型來解決了裝箱與拆箱的問題,我們可以通過使用泛型集合來避免不必要的裝箱和拆箱,例子如下:
很多地方會出現隱蔽的裝箱操作,例如,當我們需要實現自定義的結構體判等時有如下**
struct rectangle
}
我們發現,預設的簽名為將兩個比較物件轉化為object,這便會引起裝箱操作,解決辦法是實現乙個泛型iequatable介面:
struct rectangle : iequatable
}
這樣一來,在進行比較時,則會選擇引數為具體型別的equals,這樣就不會引起裝箱操作
測試如下:
namespace boxandunboxtest
public
rectangle
(int width,
int height)
}struct rectangleb
public
rectangleb
(int width,
int height)
}class
program
watch.
stop()
; console.
writeline
("會執行裝箱:"
+ watch.elapsedmilliseconds)
; watch.
restart()
;for
(int i =
0; i <
10000000
; i++
) watch.
stop()
; console.
writeline
("實現iequatable介面後不會執行裝箱:"
+ watch.elapsedmilliseconds)
; console.
readline()
;}}}
執行結果如圖
C 裝箱與拆箱
要掌握裝箱與拆箱,就必須了解cts及它的特點。net重要技術和基礎之一的cts common type system 顧名思義,cts就是為了實現在應用程式宣告和使用這些型別時必須遵循的規則而存在的通用型別系統。net將整個系統的型別分成兩大類 value type 和 reference type...
C 裝箱與拆箱
裝箱是將 值型別轉換為 引用型別 拆箱是將 引用型別 轉換為值型別 利用裝箱和拆箱功能,可通過允許 值型別的任何值與 object 型別 的值相互轉換,將值型別與引用型別鏈結起來 例如 int val 100 object obj val console.writeline 物件的值 obj 這是乙...
C 裝箱與拆箱
在前面提到了值型別和引用型別。這裡就來和大家一起了解一下,他們互相轉換的過程裝箱 boxing 拆箱 unboxing 由於c 中所有的資料型別都是由基類system.object繼承而來的,所以值型別和引用型別的值可以通過顯式 或隱式 操作相互轉換,而這轉換過程也就是裝箱 boxing 和拆箱 u...