2010-09-11 33 views
10

MSDN分類Typesvar。這是在方法 範圍內聲明VAR:A型或關鍵字

變量可以有一個隱式類型變種

什麼是「隱式類型變種」是指在這方面?

嚴格的說,如果我有它向其他程序員解釋。

我可以說; var是一個類型,還是我得說; var是一個關鍵字指示編譯器以確定所述類型本身。

說明:這不是要開始討論var,也不是要學習var的使用。一勞永逸,我想知道如何描述它,MSDN有點混亂,就是這樣。例如,

回答

14

varcontextual keyword-與yield,addget一起。

換句話說,您可以將它用作標識符而不用@作爲前綴,但它在某些地方對編譯器仍然有特殊的含義(即對於局部變量聲明,類型名稱是預期的)。

使用var聲明局部變量要求編譯器推斷基於右側表達式的變量的類型。例如:

var list = new List<string>(); 
var anon = new { Foo = "bar" }; 

類型的listList<string>;的anon類型是匿名類型,在C#還推出3.在C#3引入var的部分原因是爲了允許強烈使用變量匿名類型類型 - 變量仍具有適當的編譯時類型,甚至儘管你不能明確說明這種類型。

有一些情況下,var不起作用,但是,如果編譯器沒有足夠的信息:

var cantUseNull = null; 
var cantUseLambda = x => x.Length; 

有別人了。在每一種情況下,你可以只是投表達的右側,讓編譯器知道使用什麼 - 但在這種情況下,你可能也只是聲明變量,而不是明確。

<plug>
你可以在C# in Depth瞭解更多。幸運的是,關於這一章的章節仍然可以從first edition page免費獲得(您需要第8章)。我不記得第二版中我已經改變了這一章的多少...
</plug>

+0

您能否向我解釋一下在我引用的msdn文章中,「隱式類型var」的含義?翻譯在這裏丟失了一點;)直接編輯這個問題,你太快了...... – 2010-09-11 07:55:59

+0

@Caspar:這意味着你可以使用'var'來聲明變量的類型,在這種情況下,變量的編譯時類型是右側表達式的類型。 – 2010-09-11 07:58:41

+1

重要的是不要丟失格式,它是'隱式類型** var **'。 Var是一個隱含的類型,實際類型是由編譯器根據賦予的內容決定的,即'var i = 10;',而不是一個顯式類型的變量,即'int i = 10;'Implicit真的意味着暗示或推斷類型。這有幫助嗎? – Lazarus 2010-09-11 08:00:40

0

這是兩個都有點。從技術上講,當使用var時,變量是強類型的,但編譯器確定類型。所以我會說你說'var是一個類型'時最接近。

0

var是一個類型,像int是...但是究竟是什麼類型?

好,編譯器的工作原理是爲你(這是隱含意思)基於該行的其餘部分。

例如

var b = "ahjhsad"; 

在編譯時,VAR來代替。

變種被用作方便的簡寫爲程序員,而不必編寫

List<string> myList = new List<string>(); 

程序員可以編寫

var myList = new List<string>(); 

它意味着同樣的事情。

+0

當然,你不能擊敗雙向... – CVertex 2010-09-11 08:06:37

+0

「什麼是一種類型,完全是?「一個很好的問題。 C#規範實際上並不定義*「單詞」這個詞。它假定你知道是什麼! – 2010-09-11 14:38:16

11

我可以說var是一個,還是我不得不說var是一個關鍵字指示編譯器來確定類型?

這取決於你如何看待它。認真!

的C#編譯器上的程序3種分析,以後每次分析消耗之前的一個結果。我們做的第一種分析是詞法分析;我們將文本轉化爲一系列令牌。假設你有

class C { static void Main(){ var x = 123; } } 

我們首先確定這些令牌類標識符(C)LEFTBRACE靜態無效的標識符(主)LEFTPAREN RIGHTPAREN LEFTBRACE IDENTIFIERTHATMIGHTBEAKEYWORD(VAR)標識(x)取整數(123)SEMICOLON RIGHTBRACE RIGHTBRACE。

在這個階段的分析,「VAR」是上面有一張紙條,上面說,這可能是關鍵字var,而不是標識符VAR的標識符。

我們做的下一個分析是語法分析,其中令牌被組織成形成「分析樹」的組。在這種情況下,令牌將被組織成此樹(縮進表示在樹上築巢級)

declaration of class: CLASS 
    class name: IDENTIFIER(C) 
    class body begins: LEFTBRACE 
    declaration of method: 
     method modifier: STATIC 
     return type: VOID 
     method name: IDENTIFIER(Main) 
     formal parameter declarations: 
      formal parameter declarations begin: LEFTPAREN 
      formal parameter declarations end: RIGHTPAREN 
     method body: 
      method body begins: LEFTBRACE 
      local declaration statement: 
       type: IDENTIFIERTHATMIGHTBEAKEYWORD(var) 
       local name: IDENTIFIER(x) 
       initializer: 
       assignment operator: EQUALS 
       integer literal expression: INTEGER(123) 
       statement ends: SEMICOLON 
      method body ends: RIGHTBRACE 
    class body ends: RIGHTBRACE 

此時變種已被列爲一類,語法。如果這是一個語法合法的程序,它就在我們希望的類型聲明的地方。

但在這一點上,我們不知道「無功」是否是指一類或正被用作關鍵字。這需要語義分析。

當我們對語法分析樹進行語義分析時,我們說「好的,有一個類C,它有一個方法Main,它聲明瞭一個局部變量x,那個局部變量的類型是什麼?

此時有兩種可能性。第一種可能性是在全局名稱空間中有一個名爲「var」的類,結構,枚舉,接口或委託類型。 (在這個程序片段中沒有「使用」指令,所以我們不必檢查任何其他名稱空間,並且類型不是部分的,所以我們不必檢查任何其他類型的聲明)。我們搜索所有引用程序集的全局名稱空間,查找名爲「var」的類型。我們還對所有其他文件中的類型聲明進行語義分析,再次查找名爲var的類型。

如果我們找到一個,那麼「var」就是指那個類型。

如果我們沒有找到一個,那麼我們假設「var」被用作引入隱式類型本地的上下文關鍵字。

因此,要回答你的問題:

詞法,代碼片段「變種」是一個標識符標記,上面有一張紙條,上面寫着「對了,這實際上可能是一個關鍵字」。

從語法,令牌「VAR」是一種類型的當它出現在其中一種類型的預期語法的位置。

語義,類型語法「VAR」是一種類型的當在範圍類型稱爲變種;如果沒有這樣的類型並且「var」被用作本地聲明的類型,那麼類型語法「var」不指向類型。相反,它是編譯器推導本地實際類型的指令。

+0

感謝您的回答,我確實發現公開課var {}會按照您所描述的那樣覆蓋var關鍵字,所以您的解釋對我來說真的很有意義,謝謝! PS:這是否意味着我必須降級喬恩? ;) – 2010-09-11 14:42:33

+0

和代碼IDENTIFIERTHATMIGHTBEAKEYWORD是這樣做的事情,在var x = 123,var可能是關鍵字 – 2010-09-11 14:47:54

+0

我不知道你可以創建一個類型'var'來覆蓋關鍵字,但我想它是必須保持向後兼容性。出於好奇,有沒有辦法仍然使用'var'作爲關鍵字,即使這種類型在範圍內? – 2010-09-11 17:27:59