MSDN对var
下的Types
进行了分类。
在方法中声明的变量 scope可以具有隐式类型var
在此上下文中'隐式类型var'是什么意思?
严格说,如果我有它向其他程序员解释。
我可以说; var是 Type ,或者我必须说; var是关键字 ,指示编译器确定类型本身。
注意:这不是为了开始讨论var,也不是为了学习var的用法。对于一劳永逸,我想知道如何描述它并且msdn有点令人困惑,就是这样。
答案 0 :(得分:14)
var
是contextual keyword - 例如yield
,add
和get
。
换句话说,您可以将它用作标识符而不用@作为前缀,但在某些地方它仍然对编译器有特殊含义(即,对于局部变量声明需要类型名称)。
使用var
声明局部变量要求编译器根据右侧的表达式推断变量的类型。例如:
var list = new List<string>();
var anon = new { Foo = "bar" };
list
的类型为List<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>
答案 1 :(得分:11)
我可以说var是类型,还是我必须说var是关键字,指示编译器确定类型?
这取决于你如何看待它。认真!
C#编译器对程序进行三种分析,每次后续分析都会消耗上一次的结果。我们做的第一种分析是 lexical 分析;我们将文本转换为一系列令牌。假设你有
class C { static void Main(){ var x = 123; } }
我们首先确定这些标记是CLASS IDENTIFIER(C)LEFTBRACE STATIC VOID IDENTIFIER(主要)LEFTPAREN RIGHTPAREN LEFTBRACE IDENTIFIERTHATMIGHTBEAKEYWORD(var)IDENTIFIER(x)EQUALS INTEGER(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
此时 var已被分类为类型,语法。如果这是一个语法上合法的程序,它就在我们期望的类型声明的地方。
但是在这一点上我们不知道“var”是指一个类型还是被用作关键字。这需要语义分析。
当我们对解析树进行语义分析时,我们说“好吧,有一个C类,它有一个方法Main,它声明了一个局部变量x。那个局部变量的类型是什么?”
此时有两种可能性。第一种可能性是在全局命名空间中有一个名为“var”的类,结构,枚举,接口或委托类型。 (此程序片段中没有“using”指令,因此我们不必检查任何其他名称空间,并且类型不是部分的,因此我们不必检查任何其他类型的声明)。我们搜索所有引用程序集的全局命名空间,查找名为“var”的类型。我们还对所有其他文件中的类型声明进行语义分析,再次查找名为var。
的类型如果我们找到一个,那么“var”指的是那个类型。
如果我们没有找到,那么我们假设“var”被用作引入隐式类型本地的上下文关键字。
所以,回答你的问题:
Lexical ,代码片段“var”是一个标识符标记,上面有一个注释,“顺便说一下,这实际上可能是一个关键字”。
Gramically ,当它出现在语法中预期类型的位置时,令牌“var”是类型。
语义,类型语法“var”是类型,当范围中有一个名为var 的类型时;如果没有这样的类型并且“var”被用作本地声明的类型,则类型语法“var”不引用类型。相反,它是编译器推断本地实际类型的指令。
答案 2 :(得分:0)
这两者都有。从技术上讲,使用var时,变量是强类型的,但编译器会确定类型。所以我会说你说'var是一种类型'时你最接近。
答案 3 :(得分:0)
var 是一个类型,就像 int 是......但是它究竟是什么类型?
好吧,编译器会根据行的其余部分为你工作(这是隐含的意思)。
e.g。
var b = "ahjhsad";
在编译时, var 将替换为 string 。
var 用作程序员方便的简写,而不必写
List<string> myList = new List<string>();
程序员可以写
var myList = new List<string>();
它意味着同样的事情。