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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.NET面试题解析(02)-拆箱与装箱

發布時間:2023/11/29 asp.net 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET面试题解析(02)-拆箱与装箱 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自:??http://www.cnblogs.com/anding/p/5236739.html

常見面試題目:

1.什么是拆箱和裝箱?

2.什么是箱子?

3.箱子放在哪里?

4.裝箱和拆箱有什么性能影響?

5.如何避免隱身裝箱?

6.箱子的基本結構?

7.裝箱的過程?

8.拆箱的過程?

9.下面這段代碼輸出什么?共發生多少次裝箱?多少次拆箱?

int i = 5; object obj = i; IFormattable ftt = i; Console.WriteLine(System.Object.ReferenceEquals(i, obj)); Console.WriteLine(System.Object.ReferenceEquals(i, ftt)); Console.WriteLine(System.Object.ReferenceEquals(ftt, obj)); Console.WriteLine(System.Object.ReferenceEquals(i, (int)obj)); Console.WriteLine(System.Object.ReferenceEquals(i, (int)ftt));

? 深入淺出裝箱與拆箱

有拆必有裝,有裝必有拆。

在上一文中我們提到,所有值類型都是繼承自System.ValueType,而System.ValueType又是來自何方呢,不難發現System.ValueType繼承自System.Object。因此Object是.NET中的萬物之源,幾乎所有類型都來自她,這是裝箱與拆箱的基礎。

特別注意的是,本文與上一文有直接關聯,需要先了解上一文中值類型與引用類型的原理,才可以更好理解本文的內容。

?基本概念

拆箱與裝箱就是值類型與引用類型的轉換,她是值類型和引用類型之間的橋梁,他們可以相互轉換的一個基本前提就是上面所說的:Object是.NET中的萬物之源

先看看一個小小的實例代碼:

int x = 1023;object o = x; //裝箱int y = (int) o; //拆箱

裝箱:值類型轉換為引用對象,一般是轉換為System.Object類型或值類型實現的接口引用類型;

拆箱:引用類型轉換為值類型,注意,這里的引用類型只能是被裝箱的引用類型對象;

由于值類型和引用類型在內存分配的不同,從內存執行角度看,拆箱與裝箱就勢必存在內存的分配與數據的拷貝等操作,這也是裝箱與拆箱性能影響的根源。

?裝箱的過程

int x = 1023; object o = x; //裝箱

裝箱就是把值類型轉換為引用類型,具體過程:

  • 1.在堆中申請內存,內存大小為值類型的大小,再加上額外固定空間(引用類型的標配:TypeHandle和同步索引塊);
  • 2.將值類型的字段值(x=1023)拷貝新分配的內存中;
  • 3.返回新引用對象的地址(給引用變量object?o)

如上圖所示,裝箱后內存有兩個對象:一個是值類型變量x,另一個就是新引用對象o。裝箱對應的IL指令為box,上面裝箱的IL代碼如下圖:

?拆箱的過程

int x = 1023; object o = x; //裝箱 int y = (int) o; //拆箱

明白了裝箱,拆箱就是裝箱相反的過程,簡單的說是把裝箱后的引用類型轉換為值類型。具體過程:

  • 1.檢查實例對象(object o)是否有效,如是否為null,其裝箱的類型與拆箱的類型(int)是否一致,如檢測不合法,拋出異常;
  • 2.指針返回,就是獲取裝箱對象(object o)中值類型字段值的地址;
  • 3.字段拷貝,把裝箱對象(object o)中值類型字段值拷貝到棧上,意思就是創建一個新的值類型變量來存儲拆箱后的值;

如上圖所示,拆箱后,得到一個新的值類型變量y,拆箱對應的IL指令為unbox,拆箱的IL代碼如下:

?

?裝箱與拆箱總結及性能

裝的的什么?拆的又是什么?什么是箱子?

通過上面深入了解了裝箱與拆箱的原理,不難理解,只有值類型可以裝箱,拆的就是裝箱后的引用對象,箱子就是一個存放了值類型字段的引用對象實例,箱子存儲在托管堆上。只有值類型才有裝箱、拆箱兩個狀態,而引用類型一直都在箱子里。

關于性能

之所以關注裝箱與拆箱,主要原因就是他們的性能問題,而且在日常編碼中,經常有裝箱與拆箱的操作,而且這些裝箱與拆箱的操作往往是在不經意時發生。一般來說,裝箱的性能開銷更大,這不難理解,因為引用對象的分配更加復雜,成本也更高,值類型分配在棧上,分配和釋放的效率都很高。裝箱過程是需要創建一個新的引用類型對象實例,拆箱過程需要創建一個值類型字段,開銷更低。

為了盡量避免這種性能損失,盡量使用泛型,在代碼編寫中也盡量避免隱式裝箱。

什么是隱式裝箱?如何避免?

就是不經意的代碼導致多次重復的裝箱操作,看看代碼就好理解了

int x = 100; ArrayList arr = new ArrayList(3); arr.Add(x); arr.Add(x); arr.Add(x);

這段代碼共有多少次裝箱呢?看看Add方法的定義:

再看看IL代碼,可以準確的得到裝箱的次數:

顯示裝箱可以避免隱式裝箱,下面修改后的代碼就只有一次裝箱了。

int x = 100; ArrayList arr = new ArrayList(3); object o = x; arr.Add(o); arr.Add(o); arr.Add(o);

? 題目答案解析:

1.什么是拆箱和裝箱?

裝箱就是值類型轉換為引用類型,拆箱就是引用類型(被裝箱的對象)轉換為值類型。

2.什么是箱子?

就是引用類型對象。

3.箱子放在哪里?

托管堆上。

4.裝箱和拆箱有什么性能影響?

裝箱和拆箱都涉及到內存的分配和對象的創建,有較大的性能影響。

5.如何避免隱身裝箱?

編碼中,多使用泛型、顯示裝箱。

6.箱子的基本結構?

上面說了,箱子就是一個引用類型對象,因此她的結構,主要包含兩部分:

  • 值類型字段值;
  • 引用類型的標準配置,引用對象的額外空間:TypeHandle和同步索引塊,關于這兩個概念在本系列后面的文章會深入探討。

7.裝箱的過程?

  • 1.在堆中申請內存,內存大小為值類型的大小,再加上額外固定空間(引用類型的標配:TypeHandle和同步索引塊);
  • 2.將值類型的字段值(x=1023)拷貝新分配的內存中;
  • 3.返回新引用對象的地址(給引用變量object?o)

8.拆箱的過程?

  • 1.檢查實例對象(object o)是否有效,如是否為null,其裝箱的類型與拆箱的類型(int)是否一致,如檢測不合法,拋出異常;
  • 2.指針返回,就是獲取裝箱對象(object o)中值類型字段值的地址;
  • 3.字段拷貝,把裝箱對象(object o)中值類型字段值拷貝到棧上,意思就是創建一個新的值類型變量來存儲拆箱后的值;

9.下面這段代碼輸出什么?共發生多少次裝箱?多少次拆箱?

int i = 5; object obj = i; IFormattable ftt = i; Console.WriteLine(System.Object.ReferenceEquals(i, obj)); Console.WriteLine(System.Object.ReferenceEquals(i, ftt)); Console.WriteLine(System.Object.ReferenceEquals(ftt, obj)); Console.WriteLine(System.Object.ReferenceEquals(i, (int)obj)); Console.WriteLine(System.Object.ReferenceEquals(i, (int)ftt));

上面代碼輸出如下,至于發生多少次裝箱多少次拆箱,你猜?

False False False False False

轉載于:https://www.cnblogs.com/yan7/p/8397696.html

總結

以上是生活随笔為你收集整理的.NET面试题解析(02)-拆箱与装箱的全部內容,希望文章能夠幫你解決所遇到的問題。

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