再用2008一段時間了,但是C#3.0的新特性卻一直沒有詳細學習或是梳理過,今天邊學邊練邊整理,體驗新特性帶來的便捷。
隱含類型局部變數
關鍵字var :
一.介紹:
在C#3.0中增加了一個變數聲明var,這個聲明和JavaScript 的 var類似,但也有不同。
1. 相同點,他能夠用var來聲明任何類型的局部變數。
2. 不同點,他僅僅負責告訴編譯器,該變數需要根據初始設定式來推斷變數的類型,而且只能是局部變數。
從不同點來講,var僅僅是個關鍵字,他並不是C#3.0中的一種新的類型,而是負責告訴編譯器,該變數需要根據初始設定式來推斷變數的類型。即:從右邊自動識別物件類型,是強型別,且僅限於局部變數
var a = "abc"; 等價於: string a="abc";
var b = new []{1,2,3,5}; 等價於: int[] b = new int[]{1,2,3,5};
var c = null; 不是類型,不能用
var d; 不可以
比如:foreach(var c in list<string>)
{...}
二.注意點
1.在聲明時必須同時賦值,因為聲明依賴於賦值號右邊的運算式,假如有下面的語句:
var integer;
integer = 10;
編譯時間會報Implicitly typed locals must be initialized錯誤。
2.在使用var聲明一個局部變數後,他仍然具備強型別,(即:一但初始化完成,就不能再給變數賦與初始化實值型別不同的值了。)能夠做如下測試:
var integer = 10;
integer = " edisundong ";
編譯時間會報Cannot implicitly convert type string to int錯誤。
3. 初始化器運算式的編譯期類型不能夠是空(null)類型,編譯器無法根據null來推斷出局部變數的類型,如有下面的語句:
var integer = null;
編譯時間會報Cannot assign <null> to an implicitly typed local錯誤。
4. 初始化語句必須是個運算式,初始設定式不能包含他自身,但是能夠是包含一個對象或集合初始化器的一個new運算式(即匿名型別)。
如能夠這樣去聲明:
var coll = new Hashtable();
5.var的聲明僅限於局部變數,也能夠包含在foreach、for、using語句中。下面的使用是錯誤的:
class Program
{
private var i = 10; //全域私人變數。
static void Main(string[] args)
{ }
}
編譯時間會報The contextual keyword var may only appear within a local variable declaration錯誤。
6. 使用var定義變數和object不同,它在效率上和使用強型別方式定義變數完全一樣。但筆者建議如果事Crowdsourced Security Testing道變數的類型,盡量使用強型別方式來聲明變數。否則,就會造成由於大量使用var,而使得開發人員很難斷定某個變數是什麼類型。這樣不利於程式的維護和升級。
總結:雖然var有利有弊。
依我的個人觀點,這將降低代碼的可讀性,但是有人說這個關鍵字主要是針對LinQ而設計得,因為LinQ所涉及的類型可能相當的複雜或在申明變數時還不知道其類型。根據前人的經驗總結這個關鍵字只是為了忽悠我們,正如前面提到的,在編譯下還是強型別的,它在IL中也並沒有出現新的東西。值得注意的是用var聲明的變數一定要初始化,如果對於幾何類型的初始化時還必須指名其類型(var list = new List<int>();//int 要指出)。
另外,如果將動態語言轉換成C#語言,可以考慮使用var來定義變數。這是因為動態語言沒有類型,而要將其轉換成強型別的C#語言,就必須給變數指定個類型,但事先確定類型是很費勁的,不如將其指定成var,再由C#編譯器去確定變數的具體類型。那麼如果在轉換的過程中,發現動態語言的變數改變了類型,該怎麼辦呢?這個可以使用後面要講的“匿名類”來解決這個問題。