为什么在静态上下文中进行数组初始化?

时间:2014-10-29 14:05:15

标签: c#

让我们考虑这个课程:

class ABClass
{
    object a;
    object b;

    object[] ab = new[] {a, b};
}

这不编译:

A field initializer cannot reference the non-static field, method, or property 'TestConsole.ABClass.a'
A field initializer cannot reference the non-static field, method, or property 'TestConsole.ABClass.b'

但是,R#建议成功修复编译:

class ABClass
{
    object a;
    object b;

    object[] ab;

    public ABClass()
    {
        ab = new[] {a, b};
    }
}

为什么数组初始化似乎发生在静态上下文中?

跟进:在C#6中有auto-properties with initializers功能。它与我的问题有什么关系?

3 个答案:

答案 0 :(得分:6)

你问过:**Why** does the array initialization **seem to happen** in a static context?

不要指向你的语言规范(简单明确地说"你不能这样做,期间"),而不是考虑原因。

它发生在静态上下文中,因为否则,它将使用半构造的对象实例。字段a, b可能是,也可能未初始化。它们可以从构造函数,基本构造函数或派生构造函数,从基础/派生方法访问,这些方法可以通过虚拟/覆盖从此构造函数或基础构造函数等调用。

如果字段'允许初始化程序读取/引用其他实例字段和/或调用实例方法,编译器无法猜测字段初始化的正确顺序。

此外,请注意字段初始化过程在构造函数之前执行。允许字段访问实例字段/ props / methods意味着可以在调用构造函数(和基础构造函数)之前调用这些方法,这会导致许多奇怪和违反直觉的影响。

因此,该语言的设计是为了防止它。初始化器被简单地设计/强制在静态上下文中执行,因此您不会想要依赖半构造的对象实例功能,因此您不会过多地混淆代码。这样,你就不会意外忘记危险。你仍然可以在构造函数中完成所有这些,但是你总是知道"它的构造函数"自然你会更加谨慎。当然,你仍然可以通过调用ctor中的虚拟方法来自己动手,但是,跟踪和调试要容易得多,就像在构造函数的代码中至少执行顺序线是显而易见的,而初始化则可能不是这样。

答案 1 :(得分:1)

原因是因为Specs这么说:

  

字段初始值设定项不能引用非静态字段,方法或   属性

您的字段ab是非静态的。您无法在对象初始值设定项中访问它们。这就是你需要一个构造函数的原因。

对于C#6自动属性初始化器:

这与您的代码无关,您没有任何自动实现的属性。

答案 2 :(得分:0)

来自MSDN"实例字段的变量初始化程序无法引用正在创建的实例。"

这是源自http://msdn.microsoft.com/en-us/library/aa645759(v=vs.71).aspx

的链接

进一步阅读实例构造函数:http://msdn.microsoft.com/en-us/library/aa645602(v=vs.71).aspx