原因“A字段初始不能引用非静态字段,方法或属性” CS0236错误

问题描述:

C#不允许一个实例字段初始化引用另一个字段。 比如这段代码是无效的:原因“A字段初始不能引用非静态字段,方法或属性” CS0236错误

class A 
{ 
string s1 = ""; 
string s2 = s1; 
} 

因为 “S2” 引用 “S1”。

但为什么这是不允许的?

我首先想到的是,C#规格不保证任何初始化命令,但根据规格的顺序是声明的顺序:

变量初始化是在文本顺序执行它们出现在类声明中。

因此,如果顺序是确定性的,那么这类代码的缺陷是什么?

在此先感谢您的帮助。

编辑:

答案HPS0xA3执行彼得

  • 在继承情况下的初始化的顺序可能是非常混乱的,

  • 执行此功能会需要从编译器开发团队的一些资源没有什么好处,

  • 这是不可能的使用方法或属性的逻辑原因(感谢彼得),这样的一致性,同样是场真正的。

+0

值得注意的是,vb。net在基础对象构造之后运行字段初始化器,并允许它们引用正在构建的对象。我认为这是一件好事,尤其是在各领域之间存在不变关系的情况下。如果将构造函数参数暴露给字段初始化器不那么笨重,那将会更好。 – supercat 2013-05-09 18:23:30

本文可能会回答你的问题。

Execution Order

+1

因此,基本和派生内联实例字段初始值设定项之间的执行顺序基本不确定。 – Hps 2010-11-26 14:16:43

+0

我不能UPvote,因为我的日常限制已达到,但我一定会在第二天做。感谢您的好链接 – TalentTuner 2010-11-26 14:22:54

+0

感谢您的此链接,这无疑是答案的一部分。 – Pragmateek 2010-11-26 14:49:36

编译器可能可以检查字段的顺序,然后让初始化,如果其他领域先前已声明。

除了重新排序或重新构造破坏代码的缺陷,为什么编译器会不必要地复杂。资源是有限的,编译团队可能更喜欢更高优先级的功能。

我不确定某个字段,但拒绝字段初始值设定项访问属性或方法似乎是合理的。例如:

class A 
{ 
    string s1 = GetString(); 
    string s2 = this.MyString; 
    string s3 = "test"; 

    public string GetString() 
    { 
     // this method could use resources that haven't been initialized yet 
    } 

    public string MyString 
    { 
     get { return s3; } 
     // this field hasn't been initialized yet 
     // (okay, strings have a default value, but you get the picture) 
    } 
}