国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

輕松學習C#的裝箱與拆箱

2020-01-24 01:22:30
字體:
來源:轉載
供稿:網友

首先看一看什么是裝箱和拆箱?
       簡單的來說:
       裝箱就是值類型轉換為引用類型;
       拆箱就是引用類型轉換為值類型。
       值類型,包括原類型(Sbyte、Byte、Short、Ushort、Int、Uint、Long、Ulong、Char、Float、Double、Bool、Decimal)、枚舉 (enum) 、結構 (struct)。
       引用類型包括類、數組、接口、委托、字符串等。

裝箱:值類型到引用類型或到此值類型所實現的任何接口類型的隱式轉換
       例如: int temp = 3;
                System.Object obj = temp;
       其中,temp為值類型,在棧中分配;當分配obj這個引用類型時,我們需要在堆中分配一個obj對象,然后把temp值賦給它,這么一系列的過程就是裝箱的過程。

拆箱:從引用類型到任意值類型的顯式轉換。與裝箱不同,拆箱式顯示轉換。
       例如:int temp = 3;
                 System.Object obj = temp;
                  int i = (int) obj;
       拆箱過程中,首先來確定對象obj為一個值類型的裝箱值,然后把值賦給值類型。
隱式轉換總會成功的情況,不會拋出異常:
  (1)、從派生類到基類;
  (2)、從派生接口到基接口;
  (3)、從類到接口(該類實現了接口);
  (4)、從Null到任何類;
顯式引用轉換,以下可能拋出異常,轉換不一定成功:
  (1)、從基類到派生類;
  (2)、從接口到接口(基接口到派生接口或者倆接口沒有關系);
  (3)、從接口到類(該類實現了該接口或該類未封閉);
  (4)、從類到接口(該類未實現該接口且該類未封閉);

上面簡單的介紹了拆箱和裝箱的定義,下面就來討論一下裝箱和拆箱與堆和棧怎樣使用
       其中值類型是在棧中分配內存,本身的聲明就是一個初始化的過程,其不需要進行垃圾回收,只要超出所定義的作用范圍會自動釋放內存,而引用類型則是在堆中分配的,和java一樣,在堆種分配內存,而其托管堆進行垃圾回收。當兩種數據類型進行轉換時就引出了裝箱/拆箱。
比較裝箱和拆箱的優缺點
       裝箱和拆箱雖然滿足了兩只類型之間的轉換。但是從裝箱的過程中不難看出,每次裝箱時要在堆中new一個新的對象,當量特別大是肯定會大大影響程序的效率。事物總有兩面性,every sword has two sides,事情便簡單了,性能也下來了。所以,在應用中,我們應該盡量避免裝箱操作。
       了解了裝箱和拆箱的操作,我們可以清楚的明白:裝箱操作會導致數據在堆和棧上進行拷貝,頻繁的裝箱操作會性能損失。而相比而言拆箱過程對性能損耗還是比較小的。
裝箱和拆箱的詳細步驟

       1、裝箱(box)的詳細步驟:

      (1)、在堆上分配一個內存空間,大小等于需要裝箱的值類型對象的大小加上兩個引用類型對象都擁有的成員:類型對象指針和同步塊引用。
      (2)、把堆棧上的值類型對象復制到堆上新分配的對象。
      (3)、返回一個指向堆上新對象的引用,并且存儲到堆棧上被裝箱的那個值類型的對象里。
        這個步驟不需要程序員自己編寫,在任何出現裝箱的地方,編譯器會自動加上執行以上功能的IL代碼。
        所謂的拆箱就是裝箱對應著的概念,但拆箱的過程和裝箱并不是倒過來就是:
       2、拆箱(unbox.any)的詳細步驟
        如果為待拆箱對象為null,拋出NullReferenceException異常。
        如果引用指向的不是一個期望對象的已裝箱對象,拋出InvalidCastException異常。
      (1)、獲取已裝箱對象中各個字段的地址,這個過程就是“拆箱”
       需要說明的是一般拆箱以后會伴隨著對象的拷貝,但拷貝操作已經不是拆箱的范疇。

下面舉兩個小的例子來實現什么是裝箱、拆箱以及怎樣避免因頻繁的裝箱而耗費內存
(1)、裝箱:   

 using System;    public class Test    {          public static void Main(String[] args)         {             int i = 10;             //將值類型的i裝箱             //需要注意的是:這里的裝箱采用的是值的拷貝             object obj = i;             //檢驗是否裝箱成功了             if(obj is int)             {                Console.WriteLine("數據已經裝箱!");             }             //我們在這里更改i的值             i = 33;             Console.WriteLine("int i現在的值是:{0}",i);            Console.WriteLine("int i裝箱的值是:{0}",obj);        }     }

(2)、拆箱:

 int i = 10;     object obj = i;     int j = (int)obj;      (3)、避免頻繁的裝箱:     int i = 10;     int j = 20;     int s = 30;     Console.WriteLine("i的值為{0},j的值為{1},s的值為{2}", i.ToString(), j.ToString(), s.ToString());

以上就是介紹了C#的裝箱與拆箱,思路很清晰,涉及的內容很全面,包括裝箱和拆箱的優缺點、裝箱和拆箱的步驟等,很適合初學者進行學習。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 鹿泉市| 东源县| 聂拉木县| 蒙山县| 石泉县| 姜堰市| 六盘水市| 皮山县| 深州市| 潜江市| 建始县| 三都| 许昌市| 辉县市| 安图县| 隆昌县| 乌审旗| 合江县| 三河市| 恩施市| 莒南县| 察雅县| 屏东县| 专栏| 墨脱县| 彭山县| 宁国市| 涟源市| 洛宁县| 广丰县| 新宾| 鹤庆县| 井研县| 介休市| 渑池县| 汨罗市| 荆州市| 丽水市| 义乌市| 苏尼特左旗| 逊克县|