103

C#中不是var关键字吗?但为什么我可以这样做:

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 { }

编译器说intortrue是一个关键字,不能这样使用。为什么不一样var呢?

4

5 回答 5

101

var根据此列表,它不是关键字。

它是一个上下文关键字,因此编译器能够根据上下文确定哪个是您的类,哪个是上下文关键字,不会产生混淆。

上下文关键字是:

用于在代码中提供特定含义,但它不是 C# 中的保留字。

所以它没有保留,你可以使用它。

正如上面评论中所指出的,在Eric Lipperts 博客上讨论了差异以及在每个 c# 版本中添加的各种关键字和上下文关键字的列表

有趣的是,由于关键字集是在 C#1.0 中决定的,因此没有添加任何内容,以保持向后兼容性。

于 2012-05-11T09:43:55.613 回答
18

编译器足够聪明,知道您var用作类名的上下文永远不是关键字的上下文,因此允许它(这就是为什么它被定义为上下文关键字)。

于 2012-05-11T09:44:26.993 回答
12

另一种看待这个问题的方式:“var”作为关键字不在 C# 的第一个版本中(与“int”和“true”不同),因此您可能已经编写了一些代码,其中有一个名为“var”的类。这是非常好的和合法的。后来,当“var”被添加到语言中时,设计者非常友好,只在某些情况下将它作为关键字,所以你现有的 var 类仍然可以工作。

这是语言设计的真正挑战之一——如何在不破坏现有代码的情况下添加新功能,并且不会使新功能使用起来很麻烦。

于 2012-05-11T09:59:41.963 回答
8

在版本 3 之前的 C# 版本中,尚不支持隐式类型的局部变量var,因此没有特殊含义,可以定义名为var. 您的示例程序是合法的,因为 in 的两次出现都var引用main了 class var

C# 3 和更高版本向下兼容,因此在版本 3 之前用 C# 编写的代码仍然可以使用新的编译器进行编译。

int并且true是自 C# 1 以来的关键字。

于 2012-05-11T09:45:40.770 回答
3

关键字可以根据上下文保留。当解析源代码时,该上下文被建立为解析树的一部分。关键字的评估是在该上下文中进行的。因此,在这种情况下, var 不在保留上下文中,并且与在赋值语句中使用它时的含义不同。我相信这种灵活性的一个原因是 var 是在 C# 3 中引入的,因此将其保留在任何地方可能会破坏某些程序的向后兼容性,而将其用作变量类型声明在早期版本中不会编译,所以没有破损。

于 2012-05-11T16:22:41.640 回答