为什么类字段不能是var?

时间:2010-12-16 14:09:34

标签: c#

class A
{
    A()
    {
        var x = 5;   // this is allowed
    }

    var _x = 5;   // the compiler is unhappy
}

我想编译器必须能够推导成员变量的类型,就像它对本地变量一样。那有什么区别?

5 个答案:

答案 0 :(得分:25)

Eric Lippert在这里回答了你的问题:Why no var on fields?

基本上,对于一般情况,它需要重写C#编译器,因为它当前进行类型推断的方式不适用于var字段变量赋值的循环。

答案 1 :(得分:7)

var关键字是为匿名类型设计的,只能在方法中使用。

而且,你错了;编译器不能总是推导出var字段。

如果编译以下内容会发生什么:

class A {
    public readonly var value = B.value;
}

class B {
    public readonly var value = B.value;
}

这种情况无法使用局部变量重新创建,因为变量在定义之前无法引用。

这里的一般问题是你要求编译器消耗类型信息,同时它还在生成那些信息
Eric Lippert explains in greater depth

答案 2 :(得分:2)

我认为有两个原因:

  1. 可能需要在公共接口中声明类型声明
  2. 很难实现。 C#编译器分为多个阶段编译 首先它解析除方法体之外的所有东西,因此它知道函数体之外的所有东西。然后它可以使用该信息单独编译方法体。编译一个方法体时会发生什么对编译其他方法体时发生的事情影响不大 如果您可以对字段使用var,则字段初始值设定项的表达式主体会影响字段的类型,从而影响许多其他方法。所以它不适合编译器设计。

答案 3 :(得分:0)

但是对于

var a = SomeMethod();

编译器首先需要知道SomeMethod()的返回类型,此时它还不知道。

请参阅:http://blogs.msdn.com/b/ericlippert/archive/2009/01/26/why-no-var-on-fields.aspx

答案 4 :(得分:0)

这是猜测,但类级别字段的初始化必须作为Type的初始化(构造函数)过程的一部分完成,而方法级别变量的初始化在构造方法的堆栈帧时发生。也许这种区别与框架内如何编译这些过程(如何创建它们的实现)有关。