日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

装箱 拆箱

發(fā)布時間:2025/1/21 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 装箱 拆箱 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

裝箱(boxing):將值類型轉換為引用類型。

拆箱(unboxing):將引用類型轉換為值類型。

c#數(shù)據(jù)類型分:值類型【簡單類型(布爾類型 字符類型 實數(shù)類型)?結構類型struct??枚舉類型enum】?,?引用類型【接口類型interface??所有的數(shù)組?類類型class?委托delegate】??指針類型

?

?

在拆箱的過程中要注意以下兩點:

1. 如果對已裝箱的值類型的引用的變量為null,會引發(fā)NullRefreenceException異常

2. 如果一個引用指向的對象在拆箱時不是用的裝箱時所使用的類型,將會引發(fā)InvalidCastException異常。代碼如下:

?

1 static void Main(string[] args)
2 {
3 Int32 x = 5;?
4 Object o = x;?
5 Int16 y = (Int16)o; //引發(fā)InvalidCastException異常
6 }
7


正確的做法是,現(xiàn)將其用Int32類型來拆箱,然后再強制轉換為Int16

?

1 static void Main(string[] args)
2 {
3 Int32 x = 5;?
4 Object o = x;?
5 Int16 y = (Int16)(Int32)o;?
6 }
?

下面來看兩段程序來深入理解下裝箱和拆箱

代碼一:

1 static void Main(string[] args)
2 {
3 Int32 x = 5;?
4 Object o = x;?
5 x = 123;?
6?
7 Console.WriteLine(x + ", " + (Int32)o);?
8 }
9


上面的代碼中有多少次裝箱呢?乍一看好像就一次(Object o=x;),其實一共有三次裝箱,看看IL代碼就一目了然了。

?

程序的執(zhí)行步驟:

?

1 創(chuàng)建一個Int32的未裝箱的值類型實例x,并初始化為5.

2 創(chuàng)建Object類型的變量o,并指向x。由于引用類型的變量必須要執(zhí)行堆中的對象,所以要對x進行裝箱(第一次裝箱),并將x在堆中的引用地址存儲在o中。

3 將值123賦給未裝箱的值類型實例x中。

4 調用WriteLine方法,WriteLine方法的參數(shù)值類型為String,現(xiàn)在WriteLine方法存在三個數(shù)據(jù)項,值類型x、string類型“,”和一個已裝箱的Int32類型實例的引用o,這三個數(shù)據(jù)項必須要合并成一個string對象才能被調用。

5 調用String對象的靜態(tài)方法Concat,Concat方法有9個重載,根據(jù)那三個數(shù)據(jù)項會選擇下面方法執(zhí)行。

?

?

6 第一個參數(shù)arg0傳入的是x ,參數(shù)類型為object,所以要對x進行裝箱(第二次裝箱),將引用地址傳給arg0,arg1傳入的是字符串“,”,字符串就是引用類型,直接傳引用地址,arg2傳入的是將o拆箱然后再裝箱(第三次裝箱)的引用地址傳入。

?

上面代碼中的WriteLine方法如果直接寫成Console.WriteLine(x + ", " + o); 將會有跟高的相率,因為o本身就是Object類型,在Concat的時候不用進行裝箱拆箱。

?

?

代碼二:看看這段程序發(fā)生了幾次裝箱

?

1 static void Main(string[] args)
2 {
3 Int32 x = 5;?
4 Object o=x;?
5 x=123;?
6 Console.WriteLine(x);?
7 x = (Int32)o;?
8 Console.WriteLine(x);?
9 Console.WriteLine(o);?
10 }
11


上面的代碼只發(fā)生了一次裝箱,因為WriteLine方法的重載版本中參數(shù)類型可以為Objet或是Int32,在調用WriteLine方法是并沒有裝箱,唯一的一次裝箱是Object o=x; 。

?

代碼三:

1 static void Main(string[] args)
2 {
3 Int32 x = 5;?
4 CheckRef(x, x); //輸出不同引用
5 }
6?
7 static void CheckRef(object obj1, object obj2)
8 {
9 if (obj1 == obj2)
10 Console.WriteLine("相同引用");?
11 else
12 Console.WriteLine("不同引用");?
13 }
14

?

1 static void Main(string[] args)
2 {
3 Int32 x = 5;?
4 Object o = x;?
5 CheckRef(o,o); //輸出相同引用
6 }
7?
8 static void CheckRef(object obj1, object obj2)
9 {
10 if (obj1 == obj2)
11 Console.WriteLine("相同引用");?
12 else
13 Console.WriteLine("不同引用");?
14 }
15

執(zhí)行上面代碼將發(fā)生兩次裝箱,因為CheckRef方法的兩個參數(shù)都是Object類型,傳入的都是值類型的實例,可以講代碼改進下,先將x轉換成Object類型再傳入方法,如下:

?

改進后只進行一次裝箱操作了,效率提高了,但是會發(fā)現(xiàn)運行的結果頁發(fā)生了變化,所以這種做法在有些時候是很危險的。

裝箱拆箱操作極大的破環(huán)程序的性能,不過在Net2.0中提供了泛型集合類,所以完全可以用List 和Dictionary 來代替 原來1.0中的ArrayList和HashTable,即使是List也會比ArrayList的性能要好。

總結

以上是生活随笔為你收集整理的装箱 拆箱的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。