在學習C#基礎篇幅的時候總是逃不掉值類型和引用類型,很多新手包括我以前對它的理解也只是停留在"引用類型存儲在堆上,值類型存儲在棧上".
這個誤區主要歸咎於我們根本沒有動腦筋,第一句話是正確的,引用類型的實例總是在堆上創建的.但後一句就有問題了.設想假定一個類中有一個int類型的實例變量.
(如下代碼)
1 public class Person 2 { 3 public int Age { get; set; } 4 }
那麼在這個Person類中的該變量的值總是和對象中的其它數據在一起,也就是在堆上.事實上只有局部變量和方法參數在棧上,但是對於c#2.0更高版本,很多局部變量並不完全存放
在棧上,比如匿名函數閉包,這些特性不適合新手這裡就不說明了.
這個問題對於JavaScript程序員才學C#的時候很容易混淆.雖然C#不是完全的強類型語言(C#4.0以上允許你使用動態類型),但在C#3.0以下基本還算是強類型語言
在說明var的關鍵字之前,需要大家知道的是 C#2.0是對CLR進行了改動,但在隨後面的版本基本都沒發生重大的改動,這意味著很多特性都是編譯器在默默的幫助你,
比如C#3.0引入Var類型.為了更好的說明Var不是動態類型我還是引入一個實例
1 static void Main(string[] args) 2 { 3 4 var str = "Hello, world."; 5 6 str = 10; 7 8 }
上述代碼是無法通過編譯的,編譯器會告訴你" 無法將類型“int”隱式轉換為“string".
因為str的類型是String,在你寫申明str變量的時候就已經確定了類型了,那麼var到底有什麼用呢?
之所以使用Var隱式類型,原因很簡單,它減少代碼的輸入量,這意味增加了可讀性,尤其在涉及泛型時,類型名稱變的相當長,我還是引入一個實例
1 static void Main(string[] args) 2 { 3 4 //未使用var變量前 5 Dictionary<List<int>, IEnumerable<Person>> dic1 = new Dictionary<List<int>, IEnumerable<Person>>(); 6 7 //使用var變量後 8 var dic2 =new Dictionary<List<int>, IEnumerable<Person>>(); 9 }
可以看出使用了var的變量確實可讀性更好了,還減少了代碼量(但是並不是在任何地方都可以濫用var類型)
在聲明dic2變量的時候,實際上它是在編譯時就確定了類型,而不是發生在運行時,為了證明這點你可以把鼠標光標移到到var上 VS就會提示你使用的類型
如圖
這也證明了它確實在編譯時就確定了類型,只是編譯器幫你變的魔術而已.如果還是感到懷疑的同學可以聲明一個var number; 試試看看它是否能通過,答案肯定是否定的
因為編譯器是在編譯時推斷的,所以它肯本不知道這是什麼東東,這樣它的魔法就失靈了.
還要說明的是var不是所有的場景都可以推斷,實際上它有缺點,這裡就不列出了.
不要濫用var隱式類型
例子說明
static void Main(string[] args) { //不能直觀的知道number是什麼類型 var number = getValue(); }
上面的代碼在維護的時候不能直觀的知道number是什麼類型的變量,而需要將光標移到var上才能知道.影響閱讀
好了 暫時就說這麼多了,先洗洗睡了.如果基佬們喜歡,我後面還會列出更多常見誤區,如果有什麼說的不對的地方
歡迎大家一起切磋切磋共同學習.