最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#裝箱和拆箱的原理介紹

 更新時間:2022年03月20日 17:14:42   作者:.NET開發(fā)菜鳥  
這篇文章介紹了C#裝箱和拆箱的原理,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

我們知道,值類型的變量是在堆棧上分配內存的,而引用類型包括System.Object的對象是在堆上分配內存的,基于這一特點,當值類型被類型轉換時,會在堆棧和堆上進行一系列的操作,這就是裝箱和拆箱的來源。充分理解裝箱和拆箱,有助于程序員編寫高效率的代碼。

1、裝箱和拆箱的基本概念

我們知道,所有的值類型都繼承自System.ValueType,而System.ValueType繼承自System.Object。所有的值類型對象都分配在堆棧上,而所有的引用類型包括System.Object對象都分配在堆上。問題隨之而來,既然System.Object是所有值類型的基類,那所有的值類型必然都可以隱式的轉換成System.Object類型,此時這個對象會被放在哪里呢,堆棧上面還是堆上面?實際上,當這個轉換發(fā)生時,CLR需要做額外的工作把堆棧上的值類型移動到堆上,這個操作就被稱為裝箱。來看一個裝箱所需要的詳細步驟。

  • 在堆上分配一個內存空間,大小等于需要裝箱的值類型對象的大小加上兩個引用類型對象都擁有的成員:類型對象指針和同步塊引用。
  • 把堆棧上的值類型對象復制到堆上新分配的對象。
  • 返回一個指向堆上新對象的引用,并且存儲到堆棧上被裝箱的那個值類型的對象里。

這些步驟都不需要程序員自己編寫,在任何出現裝箱的地方,編譯器會自動地加上執(zhí)行以上功能的中間代碼。下圖展示了裝箱前后堆和堆棧的變化。

理解了裝箱之后,就可以很方便地理解拆箱操作了。所謂的拆箱,就是裝箱操作的反操作,把堆中的對象復制到堆棧中,并且返回其值。需要注意的是,拆箱操作將判斷被拆箱的對象類型和將要被復制的值類型引用是否一致,如果不一致,將會拋出一個InvalidCastException的異常。這里的類型匹配并不采用任何顯示的類型轉換。下面的代碼展示了這一特性。

static void Main(string[] args)
{
    try
    {
        Int32 i = 3;
        // 裝箱
        Object o = i;
        // 拆箱,類型轉換失敗
        Int16 j = (Int16)o;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

    Int32 ii = 3;
    // 裝箱
    Object obj = ii;
    // 拆箱
    Int16 jj = (Int16)(Int32)obj;
    Console.WriteLine("拆箱成功!");
    Console.ReadKey();
}

程序運行結果:

分析上面的代碼,在第一組裝箱拆箱操作中,代碼試圖把一個原來類型為Int32的值類型裝箱后的對象拆箱成Int16的變量,這樣的拆箱是非法的,運行時會拋出一個InvalidCastException的異常。而在第二組裝箱拆箱操作中,就進行了正確的類型匹配,拆箱順利完成。

2、裝箱和拆箱對性能的影響,以及如何避免裝箱拆箱

裝箱和拆箱都意味著堆和堆??臻g的一系列操作,毫無疑問,這些操作的性能代價是很大的,尤其對于堆上空間的操作,速度相對于堆棧的操作慢的多,并且可能引發(fā)垃圾回收,這些都將大規(guī)模地影響系統(tǒng)的性能。如何避免裝箱拆箱操作,是程序員在編寫代碼時需要時刻考慮的一個問題。裝箱和拆箱操作常發(fā)生在以下兩個場合:

  • 值類型的格式化輸出。
  • System.Object類型的容器。

第一種情況,值類型的格式化輸出往往會涉及一次裝箱操作。例如下面的兩行代碼:

int i = 10;
Console.WriteLine("i的值是:" + i);

代碼完全能夠通過編譯并且正確執(zhí)行,但卻引發(fā)了一次不必要的裝箱操作。在第2行代碼上,值類型i被作為一個System.Object對象傳入方法之中,這樣的操作完全可以通過下面的改動來避免:

int i = 10;
Console.WriteLine("i的值是:" + i.ToString());

改動后的代碼調用了i的ToString()方法來得到一個字符串對象。由于字符串是引用類型,所以改動后的代碼就不在涉及裝箱操作。

第二種情況更為常見一些。例如常用的容器類ArrayList,就是一個典型的System.Object容器。任何值類型被放入ArrayList的對象中,都會引發(fā)一次裝箱操作。而對應的,取出值類型對象就會引發(fā)一次拆箱操作。在.NET 1.1之前,這樣的操作很難避免,但在.NET 2.0推出了泛型的概念后,這些問題得到了有效的解決。泛型允許定義針對某個特定類型(包括值類型)的容器,并且有效的避免裝箱和拆箱。

三、總結

裝箱和拆箱本質上是值類型在轉換到System.Object時引發(fā)的堆棧和堆的一系列移動操作。裝箱時值類型從堆棧上被復制到堆上,而拆箱時從堆上復制到堆棧上。裝箱和拆箱對性能有比較大的影響,應該避免任何沒有必要的裝箱和拆箱操作。

在可以確定類型的情況下應該使用泛型技術而避免使用針對System.Object類型的容器,這樣可以有效避免大規(guī)模地使用裝箱和拆箱操作。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • c#使用ManagedWifi查看當前Wifi信號并選擇wifi的示例

    c#使用ManagedWifi查看當前Wifi信號并選擇wifi的示例

    這篇文章主要介紹了c#使用ManagedWifi查看當前Wifi信號并選擇wifi的示例,需要的朋友可以參考下
    2014-04-04
  • C#使用Fleck實現創(chuàng)建WebSocket服務器

    C#使用Fleck實現創(chuàng)建WebSocket服務器

    這篇文章主要為大家詳細介紹了C#如何使用Fleck實現創(chuàng)建WebSocket服務器,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-01-01
  • 純C#實現Hook功能詳解

    純C#實現Hook功能詳解

    這篇文章主要介紹了純C#實現Hook功能詳解,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • Winform窗體縮放下使用剪切板功能出現頁面閃動解決分析

    Winform窗體縮放下使用剪切板功能出現頁面閃動解決分析

    這篇文章主要介紹了Winform窗體縮放下使用剪切板功能出現頁面閃動解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • C#中利用Lotus notes公共郵箱發(fā)送郵件的方法

    C#中利用Lotus notes公共郵箱發(fā)送郵件的方法

    這篇文章主要給大家介紹了關于C#中利用Lotus notes公共郵箱發(fā)送郵件的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定參考學習價值,需要的朋友們下面來一起看看吧。
    2018-02-02
  • winform 使用Anchor屬性進行界面布局的方法詳解

    winform 使用Anchor屬性進行界面布局的方法詳解

    這篇文章主要介紹了winform 使用Anchor屬性進行界面布局的方法,有需要的朋友可以參考一下
    2013-12-12
  • 避免在C#循環(huán)中使用await的方法小結

    避免在C#循環(huán)中使用await的方法小結

    在C#中,異步編程因其能夠提升應用程序性能和響應能力而變得越來越流行,async和await關鍵字使得編寫異步代碼變得更加容易,但如果使用不當,它們也可能引入一些陷阱,所以本文我們將探討為什么應該避免在C#循環(huán)中使用await,并討論一些更高效地處理異步操作的替代方法
    2024-09-09
  • WPF自定義路由事件的實例教程

    WPF自定義路由事件的實例教程

    WPF中有兩種事件模型,一種是在WinForm時代就存在的CLR事件,另一種是WPF時代的路由事件,這篇文章主要給大家介紹了關于WPF自定義路由事件的相關資料,需要的朋友可以參考下
    2021-09-09
  • C# 泛型字典 Dictionary的使用詳解

    C# 泛型字典 Dictionary的使用詳解

    本文主要介紹了C# 泛型字典 Dictionary的使用詳解,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • Unity UGUI教程之實現滑頁效果

    Unity UGUI教程之實現滑頁效果

    使用UGUI提供的ScrollRect和ScrollBar組件實現基本滑動以及自己控制每次移動一頁來達到滑頁的效果。具體實現思路請參考下本教程
    2016-04-04

最新評論

定安县| 博客| 湖北省| 温宿县| 瑞安市| 手游| 吉安县| 柳州市| 新乐市| 广丰县| 边坝县| 通许县| 施秉县| 敦煌市| 满洲里市| 临武县| 松滋市| 北碚区| 阜宁县| 西和县| 铜鼓县| 永泰县| 海门市| 巴林右旗| 佳木斯市| 嘉荫县| 伊春市| 鲁甸县| 孝昌县| 拉萨市| 墨脱县| 上林县| 融水| 灌云县| 阿拉善盟| 云浮市| 富阳市| 新化县| 南通市| 安阳市| 岳阳市|