【问题标题】:Why can I create a class named "var"?为什么我可以创建一个名为“var”的类?
【发布时间】:2012-05-11 09:41:09
【问题描述】:

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

public class var { }

public class main
{
    public static void main(string[] args)
    {
        var testVar = new var();
    }
}

代码中使用的var 是在main 类之前声明的var 类。编译器甚至没有抱怨。

当我这样做时:

public class int { }

或者这个:

public class true { }

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

【问题讨论】:

  • 您为什么要这样做?如此混乱且难以阅读。
  • 问一个好问题!
  • 你也可以在方法中做var var = "var";。毕竟是星期五。
  • 我猜他们这样做是为了向后兼容代码创建 before “var” 意味着任何特别的东西。

标签: c# .net-4.0


【解决方案1】:

var 不是关键字according to this list

它是一个上下文关键字,所以编译器可以根据上下文来决定哪个是你的类,哪个是上下文关键字,不会产生混淆。

上下文关键字是:

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

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

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

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

【讨论】:

  • 然而它在这里被归类为“C#关键字”msdn.microsoft.com/en-us/library/bb383973.aspx ...令人困惑!
  • 但它是Contextual Keyword"上下文关键字用于在代码中提供特定含义,但它在C#中不是保留字。一些上下文关键字,例如partial和where,在两个方面有特殊含义或更多上下文。”
  • @TimSchmelter 然后“var”是一个“关键字”。只是不是“保留词”,对吧?
  • 我猜这是为了保持与旧代码的兼容性 - 如果有人有一个名为 var 的类,那么升级 C# 时并非一切都会中断。
  • @CallumRogers:这正是 C# 团队这样做的原因。与后来引入的其他“关键字”相同,例如 from、join 等(顺便说一句,都是上下文相关的)。
【解决方案2】:

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

【讨论】:

  • 我认为这个答案至少有点误导。编译器并不完全“足够聪明”,无法确定var 是否被用作var testVar = new var(); 等代码中的关键字。是的,就是否定义了名为 var 的自定义类型而言,上下文在其中发挥了作用,但这正是因为编译器在这些情况下不够聪明知道var testVar 是否引用到类var 或关键字var,它在这种上下文中默认为类。如果 var 关键字命名不同,它可以在相同的“上下文”中使用。
  • 对比其他上下文关键字,例如add - 在这里,编译器确实知道每次出现该关键字是否意味着(事件声明;标识符在那里没有任何意义),或者代码是否引用标识符(声明中的类型或名称,在方法主体中使用标识符;关键字在那里没有任何意义)。
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    在版本 3 之前的 C# 版本中,尚不支持 implicitly typed local variables,因此 var 没有特殊含义,可以定义名为 var 的变量和类。您的示例程序是合法的,因为在 main 中出现的 var 都引用了 var 类。

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

    inttrue 是自 C# 1 以来的关键字。

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-12-05
        • 2019-07-12
        • 2016-09-26
        • 1970-01-01
        • 1970-01-01
        • 2015-03-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多