程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 裝箱與拆箱的走走停停,裝箱走走停停

裝箱與拆箱的走走停停,裝箱走走停停

編輯:C#入門知識

裝箱與拆箱的走走停停,裝箱走走停停


上一篇簡單述說了值類型與引用類型的關系,那麼不能不說說值類型的拆箱與裝箱:

      將值類型裝箱就相當於把它包裝起來給人看,"你瞧,我現在是引用類型了",顧名思義拆箱就是將包裝卸下來"其實我是值類型"。

   在將值類型利用裝箱機制打包成引用時他要進行許多的打扮:

      1.首先要給他一個空間(在托管堆中分配內存),多大呢,要必須要容得下包裝所需要的物件化妝品之類的(各自段所需的內存量),此外還要有專家設計師吧(類型對象指針和同步塊索引兩個額外的成員);

      2.空間有了,他就要開始將自己的東西和物件搬過來(只類型的字段復制到新分配的堆內存);

      3.一切准備就緒,不過此時出了意外,他被人頂替冒充了,而冒充它的那個人很清楚這個房間的位置(返回對象地址,改地址就是對象引用)。

上面解釋可能會有點牽強,給個例子一目了然:

 1 struct Point{public int x,y;}
2 public sealed class Program{ 3 public static void Main() 4 { 5 ArrayList a = new ArrayList(); 6 Point p; 7 p.x=1;p.y=1; 8 a.Add(p); 9 } 10 }

最簡單不過的代碼了,由於Add()方法參數是Object類型,所以在執行時要進行一次裝箱操作:Point值類型實例p中的字段會復制到新分配的Point對象中,已裝箱的Point對象的地址返回並傳給Add方法,需要說明的是Point對象此時是引用類型存在於堆中,Point值類型變量p可被重用,a已經不知道他的任何事情,由此可見已裝箱值類型生存期超過了未裝箱值類型的生存期。

-------------------------------------------------------------------------------

接下來說說拆箱:

  緊接上段代碼,如若Point p = (Point)a[0];代碼執行時,就進行了一次拆箱:

  一個人他知道了那個房間的地址,他把東西都要了回來,而東西可能已經變了(拆箱不是簡單的裝箱逆過程,它的代價比裝箱要低,拆箱就是獲取指針的過程,該指針指向包含在一個對象中的原始值類型(數據字段),指針指向的是已裝箱實例中未裝箱的部分,不要求在內存中復制任何字節);

  拆箱時要注意:1.包含"對已裝箱類型實例的引用"的變量為null時,會拋出異常(他都沒有房間,也沒有物件,你找個P啊)

         2.如果引用的對象不是所需值類型的已裝箱實例,拋出異常(張三的東西,李四來要,對方能給嗎);

 

--------------------------------------------------------------------------------

下面來做個腦筋急轉彎:

1 public static void Main(){
2         int v=5;
3         Object o = v;
4         v=123;
5         Console.WriteLine(v+","+(int)o);
6 }

問:上面代碼發生了多少次裝箱?想好在打開。。。

三次,一次很好理解,剩下的兩次,對比Console.WriteLine參數即可理解 View Code

 

部分內容參考自《CLR C#》

   

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved