在C#中相信大家對於 值類型 並不陌生因為它在我們代碼設計中是不可缺少的那麼究竟什麼是 值類型 呢? 值類型 就是 我們用到的 IntInt這些數值類型嗎?
我們知道在C#中所有的類型繼承於SystemObject根類型這也就意味著就代碼層面來講在C#中所有的類型都是Class即一切都是Class類型既然全部都是Class類型那麼值類型在哪裡呢?我們可以發現在C#中SystemIntSystemIntSystemBoolean等等這些常用的類型都是Struct 結構類型那麼結構類型是什麼下面我們定義一個結構然後通過IL Disassemble 工具來查看編譯的中間代碼便可以得到結果
public struct CustomerStruct
{
public string Name{get;set;}
}
代碼非常簡單我們就定義一個struct類型並且包含一個Name屬性
看到上面這幅圖相信大家都已經看到定義一個struct類型實際上編譯把你所定義的類型繼承了SystemValueType類型換句話說在C#中我們經常使用的SystemIntSystemIntSystemBoolean這些數值結構類型都是繼承於SystemValueType類型而SystemValueType又是繼承於SystemObject根類型即驗證我開始所講到的在C#中一切類型都是Class
之所以存在值類型 這個概念其實是因為C#中的某些類型有這特殊的地位(即繼承於SystemValueType的類型)CLR會特殊的對待這些類型
看下面這行代碼
Int a = new SystemInt() ;
CustomerStruct customer = new CustomerStruct() ;
首先為什麼對於數值類型也可以使用 new 來進行內存分配呢? 上面已經講到因為他們都是Class類型當然可以使用new 來進行內存分配
其次CLR執行這樣的代碼的時CLR 通過反射(有待考察)或者其他途徑來獲知所要請求分配內存的類型是否繼承於SystemValueType如果是的話那麼就在棧上進行分配如果不是的話那麼就是我們所說的引用類型就在托管堆上分配內存以及棧上分配對應的引用變量這些一切都是CLR做的工作
我們再來看看裝箱操作
object o = new object();
Int aaa = ;
o = aaa; //這裡會發生裝箱操作
我們都知道當CLR執行到 o = aaa;這條語句時會發生裝箱操作為什麼會發生裝箱操作呢?這是因為CLR 知道引用變量o所要引用的類型aaa是繼承於SystemValueType類型的繼承於SystemValueType的類型都是在棧上分配的而其它則是在托管堆上分配的所以會CLR會弄得aaa的副本弄到托管堆上去這一切也都是CLR的工作
由此我們可以得出結論:
在C#中 就代碼層面上講 所有的類型都是Class類型
所謂的 值類型 != 數值類型而是所有繼承於SystemValueType 的類型
值類型 得到的語言級別的支持CLR知道如何對 值類型 這樣的Class類型進行內存分配和處理
綜上所述個人愚見有什麼不對的地方希望大家幫忙指出共同學習共同進步
From:http://tw.wingwit.com/Article/program/net/201311/12889.html