2010-11-26 32 views
6

C#不允許一個實例字段初始化引用另一個字段。 比如這段代碼是無效的:原因「A字段初始不能引用非靜態字段,方法或屬性」 CS0236錯誤

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

因爲 「S2」 引用 「S1」。

但爲什麼這是不允許的?

我首先想到的是,C#規格不保證任何初始化命令,但根據規格的順序是聲明的順序:

變量初始化是在文本順序執行它們出現在類聲明中。

因此,如果順序是確定性的,那麼這類代碼的缺陷是什麼?

在此先感謝您的幫助。

編輯:

答案HPS0xA3執行彼得

  • 在繼承情況下的初始化的順序可能是非常混亂的,

  • 執行此功能會需要從編譯器開發團隊的一些資源沒有什麼好處,

  • 這是不可能的使用方法或屬性的邏輯原因(感謝彼得),這樣的一致性,同樣是場真正的。

+0

值得注意的是,vb。net在基礎對象構造之後運行字段初始化器,並允許它們引用正在構建的對象。我認爲這是一件好事,尤其是在各領域之間存在不變關係的情況下。如果將構造函數參數暴露給字段初始化器不那麼笨重,那將會更好。 – supercat 2013-05-09 18:23:30

回答

4

本文可能會回答你的問題。

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

2

編譯器可能可以檢查字段的順序,然後讓初始化,如果其他領域先前已聲明。

除了重新排序或重新構造破壞代碼的缺陷,爲什麼編譯器會不必要地複雜。資源是有限的,編譯團隊可能更喜歡更高優先級的功能。

5

我不確定某個字段,但拒絕字段初始值設定項訪問屬性或方法似乎是合理的。例如:

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) 
    } 
} 
相關問題