2010-02-03 135 views
2

我有需要的對象被創建時要進行初始化的兩個私人列表。第二個列表取決於第一個列表。我可以這樣做:初始化私有成員C#

public class MyClass 
    { 
     private List<T> myList = new List<T>(); 
     private ReadOnlyCollection<T> myReadOnlyList = myList.AsReadOnly; 

     ... 
    } 

第二個列表是隻讀的第一個包裝。

我能想到的是C#將在此爲了每次運行時執行該兩行呢?

或者我應該把這個初始化在構造函數?

編輯:
對不起,愚蠢的問題。我試了一下,編譯說:

Error 1 A field initializer cannot reference the 
      non-static field, method, or property... 
+0

關於您的編輯,請參閱下面的答案:http://stackoverflow.com/questions/2194531/initializing-private-members-c/21​​94559#2194559。 – jason 2010-02-03 19:04:13

回答

11

號如果你想基於類內的一個獨立的變量初始化變量,你需要做到這一點在構造函數中:

public class MyClass 
{ 
    private List<T> myList = new List<T>(); 
    private ReadOnlyCollection<T> myReadOnlyList; 
    public MyClass() 
    { 
     myReadOnlyList = myList.AsReadOnly; 
    } 

} 

內聯intializers總是在靜態上下文中運行,這意味着您無法訪問類中的成員變量。但是,在構造函數內部,您可以執行此操作。內聯的初始化器將出現在構造函數之前,這就是爲什麼我可以將列表初始化就緒的原因。

+1

爲什麼downvotes?我真的很好奇...... – 2010-02-03 18:59:31

+0

經過11個月的會員資格,你應該對這裏的沉默駕駛風格非常熟悉;) – 2010-02-03 19:01:38

+0

@Mehrdad:是的,但是我總是很好奇爲什麼人們隨機抽查 - 所以我通常會問。我偶爾會得到迴應;)[就我個人而言,當我因爲理由而陷入低谷時,我喜歡,因爲它通常是一個學習機會。] – 2010-02-03 19:04:38

1

是的,你應該把myReadOnlyList的初始化在構造函數中,但爲了保持一致性我建議把無論是在構造函數中。

4

我可以期待c#在每次運行時都按這個順序執行這兩行嗎?

是,實例變量初始化時的法律(見下文),在它們出現的順序運行。我參考該規範的第10.11.2節:

這對應於在進入構造函數時和直接基類構造函數的隱式調用之前立即執行的賦值序列。變量初始值設定項按它們出現在類聲明中的文本順序執行。

但是,字段初始值設定項無法像您所做的那樣引用非靜態字段。您的代碼不合法​​。這是規範的第10.5.5.2節:

實例字段的變量初始值設定項無法引用正在創建的實例。因此,在變量初始值設定項中引用它是編譯時錯誤,因爲變量初始值設定項通過簡單名稱引用任何實例成員的編譯時錯誤。

關於你提到的第二個問題:

或者我應該把這個初始化在構造函數?

每以上,你別無選擇。至少您必須在構造函數中初始化myReadOnlyList,因爲它指向實例字段myList。爲了清楚起見,我會把兩者都放在構造函數中。

最後一個註釋,在一個單獨的問題上。即使下面是不合法的:

public class MyClass { 
    private List<T> myList;public class MyClass 
    private ReadOnlyCollection<T> myReadOnlyList; 
    public MyClass() { 
     myList = new List<T>(); 
     myReadOnlyList = myList.AsReadOnly; 

} 

這是因爲你還沒有宣佈MyClass作爲一個泛型類。將public class MyClass替換爲public class MyClass<T>

+0

「是的,當合法的實例變量初始值設定項(見下文)按照它們的順序運行出現。」 - 側注:部分類的不同「部分」中初始值設定項的評估順序未定義。 – 2010-02-03 19:11:58