不是var
C#中的关键字?但为什么我可以这样做:
public class var { }
public class main
{
public static void main(string[] args)
{
var testVar = new var();
}
}
代码中使用的var
是在var
类之前声明的main
类。并且编译器甚至没有抱怨。
当我这样做的时候:
public class int { }
或者这个:
public class true { }
编译器说int
或true
是一个关键字,不能像那样使用。为什么与var
不一样?
答案 0 :(得分:102)
var
不是关键字according to this list。
它是一个上下文关键字,因此从上下文中,编译器能够决定哪个是您的类,哪个是上下文关键字,并且不会出现混淆。
上下文关键字是:
用于在代码中提供特定含义,但它不是 C#中的保留字。
因为它没有保留,你可以使用它。
正如上面的评论中所指出的那样,讨论了差异以及在Eric Lipperts blog
上每个版本的c#中添加的各种关键字和上下文关键字的列表值得注意的是,由于在C#1.0中确定了一组关键字,因此没有添加,以保持向后兼容性。
答案 1 :(得分:18)
编译器非常聪明,知道您使用var
作为类名的上下文永远不是关键字的上下文所以允许它(这就是为什么它被定义为contextual keyword)
答案 2 :(得分:12)
另一种看待这种情况的方式:作为关键字的“var”不在C#的第一个版本中(与“int”和“true”不同),所以你可能编写了一些代码,其中有一个名为“var”的类”。这非常好,合法。然后,当“var”被添加到语言中时,设计人员非常友好,只能在某些上下文中将其设为关键字,因此您现有的var类仍然有效。
这是语言设计的真正挑战之一 - 如何在不破坏现有代码的情况下添加新功能,并且不会使新功能使用起来很麻烦。
答案 3 :(得分:8)
在版本3之前的C#版本中,implicitly typed local variables尚不支持,因此var
没有特殊含义,可以定义名为var
的变量和类。您的示例程序是合法的,因为var
中出现的main
两个都引用了类var
。
C#3及更高版本向下兼容,因此在版本3之前用C#编写的代码仍然可以编译新的编译器。
int
和true
是自C#1以来的关键字。
答案 4 :(得分:3)
关键字可以在上下文中保留。解析源代码时,该上下文将作为解析树的一部分建立。关键字的评估发生在该上下文中。因此,在这种情况下,var不在保留上下文中,并且与在赋值语句中使用它时的含义不同。我相信这种灵活性的一个原因是在C#3中引入了var,所以在任何地方保留它可能会破坏某些程序的向后兼容性,而将它用作变量类型声明则不会在早期版本中编译,所以没有破损。