var:a Type或关键字

时间:2010-09-11 07:52:15

标签: c# language-features

MSDNvar下的Types进行了分类。

  

在方法中声明的变量   scope可以具有隐式类型var

在此上下文中'隐式类型var'是什么意思?

严格说,如果我有它向其他程序员解释。

我可以说; var是 Type ,或者我必须说; var是关键字 ,指示编译器确定类型本身。

注意:这不是为了开始讨论var,也不是为了学习var的用法。对于一劳永逸,我想知道如何描述它并且msdn有点令人困惑,就是这样。

4 个答案:

答案 0 :(得分:14)

varcontextual keyword - 例如yieldaddget

换句话说,您可以将它用作标识符而不用@作为前缀,但在某些地方它仍然对编译器有特殊含义(即,对于局部变量声明需要类型名称)。

使用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>();

它意味着同样的事情。