在C#中實值型別的變數直接儲存資料,而參考型別的變數持有的是資料的引用,資料存放區在資料堆中。
常見的實值型別資料有:整值型(整形,浮點型,十進位型),布爾類型,枚舉類型;
參考型別有:介面,數組,Object類型,類,委託,字串,null類型。
在C#中每種類型的儲存方式有兩種:1)分配在託管棧中;2)分配在託管堆中;
記憶體的分配有CLR管理(即通用語言執行平台),這兩種方法的區別是:
1)分配在託管棧中的變數會在建立它們的方法返回時自動釋放,例如在一個方法中聲明Char型的變數UserInput=C,當執行個體化它的方法結束時,UserInput變數在棧上佔用的記憶體就會自動釋放;
2)分配在託管堆中的變數並不會在建立它們的方法結束時釋放記憶體,它們所佔用的記憶體會被CLR中的記憶體回收機制釋放。
看下面的代碼:
1 static void Main(string[] args) 2 { 3 //當nStudent聲明並賦值是,這時在託管棧上就會開闢一塊記憶體來儲存nStudent的值,當執行個體化nStudent的Main()方法結束時, 4 //nStudent在託管棧上佔用的記憶體會自動釋放。 5 int nStudent = 0; 6 //當聲明strStuName時,這個時候“小明”儲存在託管堆中,而託管棧中儲存的是strStuName指向的引用。 7 string strStuName = "小明"; 8 9 Console.WriteLine("學生的總數是{0},五號的名字是{1}", nStudent, strStuName);10 Console.ReadKey();11 }
裝箱和拆箱
當實值型別的資料轉換成參考型別時,CLR會先在託管堆配置一塊記憶體,將實值型別的資料複製到這塊記憶體,然後再讓託管棧上的參考型別的變數指向這塊記憶體,這樣的過程稱為裝箱。相反的話,有參考型別轉換成實值型別的話就稱為拆箱。
一般情況下,.NET會主動的幫我們完成裝箱操作,但是拆箱並非主動,我們必須知道拆箱對象的實力類型,然後明確的去執行拆箱操作。
1 int BirthdayNum = 1989;2 object BoxBirthdayNum = BirthdayNum;//系統自動裝箱3 int nBirthdayNum = (int)BoxBirthdayNum;//明確資料類型的拆箱
因為花費了更多的時間,所以裝箱和拆箱對程式的效能有一定的影響。
--------------------------------------------------------------------------------------------------------------------------------------
類型推斷
從C#3.0開始,C#引入了一個隱式類型推斷的關鍵字var,編譯器可以通過它的初始值來判斷變數的具體類型。var只能用於局部變數的聲明,不能用於欄位級的變數聲明。使用var關鍵字時,var必須得有初始值,這樣編譯器才能判斷是否是真實變數。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 var i = 10;//隱式類型 6 int m = 10;//顯示類型 7 8 var Program=new Program(); 9 Program.nAge = 20;10 Program.SayHello();11 }12 13 private int nAge;14 public void SayHello()15 {16 var message = "my age is {0}";17 Console.WriteLine(message, nAge);18 }19 }
message初始值的變數為字串類型,因此編譯器可以推斷其類型為String類型。