var i = 10; // 隱式類型 int i = 10; // 顯式類型
下面的示例演示兩個查詢表達式。 在第一個表達式中,var
的使用是容許的,但不是必需的,由於查詢結果的類型能夠明確表述爲 IEnumerable<string>
。 不過,在第二個表達式中,var
容許結果是一系列匿名類型,且相應類型的名稱只可供編譯器自己訪問。 若是使用 var
,便沒法爲結果新建類。 請注意,在示例 #2 中,foreach
迭代變量 item
必須也爲隱式類型。html
// 示例 #1: 當 select 子句指定字符串時,var是可選的 string[] words = { "apple", "strawberry", "grape", "peach", "banana" }; var wordQuery = from word in words where word[0] == 'g' select word; // 由於序列中的每一個元素都是字符串,而不是匿名類型,因此var在這裏也是可選的。 foreach (string s in wordQuery) { Console.WriteLine(s); } // 示例 #2: var 是必需的,由於select子句指定匿名類型 var custQuery = from cust in customers where cust.City == "Phoenix" select new { cust.Name, cust.Phone }; // 必須使用var,由於序列中的每一個項都是匿名類型 foreach (var item in custQuery) { Console.WriteLine("Name={0}, Phone={1}", item.Name, item.Phone); }
可聲明局部變量而無需提供顯式類型。 var
關鍵字指示編譯器經過初始化語句右側的表達式推斷變量的類型。 推斷類型能夠是內置類型、匿名類型、用戶定義類型或 .NET Framework 類庫中定義的類型。 有關如何使用 var
初始化數組的詳細信息,請參閱隱式類型化數組。express
如下示例演示使用 var
聲明局部變量的各類方式:數組
// i 被編譯成 int 類型 var i = 5; // s 被編譯成 string 類型 var s = "Hello"; // a 被編譯成 int[] 數組 var a = new[] { 0, 1, 2 }; // expr 被編譯成 IEnumerable<Customer> 或者 IQueryable<Customer> 類型 var expr = from c in customers where c.City == "London" select c; // anon 被編譯成匿名類型 var anon = new { Name = "Terry", Age = 34 }; // list 被編譯成 List<int> 集合 var list = new List<int>();
重要的是瞭解 var
關鍵字並不意味着「變體」,而且並不指示變量是鬆散類型或是後期綁定。 它只表示由編譯器肯定並分配最適合的類型。app
在如下上下文中,可以使用 var
關鍵字:ide
在局部變量(在方法範圍內聲明的變量)上,如前面的示例所示。函數
在 for 初始化語句中ui
for(var x = 1; x < 10; x++)
foreach(var item in list){...}
using (var file = new StreamReader("C:\\myfile.txt")) {...}
有關詳細信息,請參閱如何:在查詢表達式中使用隱式類型本地變量和數組。spa
在許多狀況下,使用 var
是可選的,只是一種語法便利。 可是,在使用匿名類型初始化變量時,若是須要在之後訪問對象的屬性,則必須將變量聲明爲 var
。 這是 LINQ 查詢表達式中的常見方案。 有關詳細信息,請參閱匿名類型。code
從源代碼角度來看,匿名類型沒有名稱。 所以,若是使用 var
初始化了查詢變量,則訪問返回對象序列中的屬性的惟一方法是在 foreach
語句中將 var
用做迭代變量的類型。htm
class ImplicitlyTypedLocals2 { static void Main() { string[] words = { "aPPLE", "BlUeBeRrY", "cHeRry" }; // 若是查詢生成一系列匿名類型,則在foreach語句中使用var訪問屬性。 var upperLowerWords = from w in words select new { Upper = w.ToUpper(), Lower = w.ToLower() }; // 執行查詢 foreach (var ul in upperLowerWords) { Console.WriteLine("Uppercase: {0}, Lowercase: {1}", ul.Upper, ul.Lower); } } } /* 輸出: Uppercase: APPLE, Lowercase: apple Uppercase: BLUEBERRY, Lowercase: blueberry Uppercase: CHERRY, Lowercase: cherry */
如下限制適用於隱式類型化變量聲明:
僅當局部變量在相同語句中進行聲明和初始化時,才能使用 var
;變量不能初始化爲 null,也不能初始化爲方法組或匿名函數。
var
不能在類範圍內對字段使用。
使用 var
聲明的變量不能在初始化表達式中使用。 換句話說,此表達式是合法的: int i = (i = 20);
,可是此表達式會生成編譯時錯誤:var i = (i = 20);
不能在相同語句中初始化多個隱式類型化變量。
若是一種名爲 var
的類型處於範圍內,則 var
關鍵字會解析爲該類型名稱,不會被視爲隱式類型化局部變量聲明的一部分。
帶 var
關鍵字的隱式類型只能應用於本地方法範圍內的變量。 隱式類型不可用於類字段,由於 C# 編譯器在處理代碼時會遇到邏輯悖論:編譯器須要知道字段的類型,但它在分析賦值表達式前沒法肯定類型,而表達式在不知道類型的狀況下沒法進行計算。 考慮下列代碼:
private var bookTitles;
bookTitles
是類型爲 var
的類字段。 因爲該字段沒有要計算的表達式,編譯器沒法推斷出 bookTitles
應該是哪一種類型。 此外,向該字段添加表達式(就像對本地變量執行的操做同樣)也是不夠的:
private var bookTitles = new List<string>();
當編譯器在代碼編譯期間遇到字段時,它會在處理與其關聯的任何表達式以前記錄每一個字段的類型。 編譯器在嘗試分析 bookTitles
時遇到相同的悖論:它須要知道字段的類型,但編譯器一般會經過分析表達式來肯定 var
的類型,這在事先不知道類型的狀況下沒法實現。
你可能會發現,對於在其中難以肯定查詢變量的確切構造類型的查詢表達式,var
也可能會十分有用。 這可能會針對分組和排序操做發生。
當變量的特定類型在鍵盤上鍵入時很繁瑣、或是顯而易見、或是不會提升代碼的可讀性時,var
關鍵字也可能很是有用。 var
採用此方法提供幫助的一個示例是針對嵌套泛型類型(如用於分組操做的類型)。 在下面的查詢中,查詢變量的類型是 IEnumerable<IGrouping<string, Student>>
。 只要你和必須維護你的代碼的其餘人瞭解這一點,使用隱式類型化實現便利性和簡便性時便不會出現問題。
// 與前面的示例相同,只是咱們使用整個姓氏做爲鍵。 // 查詢變量是IEnumerable<igrouping<string,student>> var studentQuery3 = from student in students group student by student.Last;
可是,使用 var
至少有可能使代碼對其餘開發人員更加難以理解。 爲此,C# 文檔一般只在須要時才使用 var
。