你真的瞭解裝箱(Boxing)和拆箱(Unboxing)嗎?

所謂裝箱就是 裝箱是將值類型轉換爲 object 類型或由此值類型實現的任一接口類型的過程。而拆箱就是反過來了。不少人可能都知道這一點,可是是否真的就很瞭解boxing和unboxing了呢?能夠看下下面一段代碼,裏面發生了幾回裝箱過程?html

public static void Main(string[] args)
        {
            Int32 v = 5;
            Object o = v;
            v = 123;
            Console.WriteLine(v+" , "+(Int32)o);
        }

很多人可能認爲只有一次裝箱,其實裏面發生了3次裝箱過程,是否是很意外!
  第一次很明顯,就在 Object o = v;時發生。
  第二次和第三次都是發生在Writeline()方法裏面了。調用此方法是要求獲取一個String對象,可是,當前沒有字符串對象,它只有三個數據項能夠用:一個未裝箱的Int32值類型的實例(v),一個String(是一個引用類型),以及一個已經裝箱的Int32值類型實例的引用(o),它須要轉化成一個未裝箱Int32的值類型。因此必須以某種方式對這些數據進行合併,以建立一個String。
spa

  爲了建立String,C#編譯器會生成代碼來調用String對象的靜態方法Concat。這個方法有好幾個重載版本,因爲須要把三個數據項鍊接起來,因此編譯器選擇的是:code

public static string Concat(
    Object arg0,
    Object arg1,
    Object arg2
)

  爲第一個參數arg0傳入的是值類型v,但arg0是一個Object,因此必須對v進行裝箱,並將已經裝箱的v的地址傳給arg0。爲arg1參數傳遞的是一個" , ",它本質上是一個String對象的引用,無需裝箱。最後對於arg2,o(一個Object對象的引用)會轉換成一個Int32,這要求執行一次拆箱操做(但不緊接着執行一次複製操做),從而獲取在已裝箱Int32中未裝箱的Int32的地址。這個未裝箱的Int32實例必須再次裝箱,並將新的已裝箱實例的地址傳給Concat的arg2參數。htm

  而後Concat調用指定的每一個對象的TosSring方法,並鏈接每一個對象的字符串表示,最終由WriteLine方法顯示出來。對象

相關文章
相關標籤/搜索