2015-06-11 43 views
5

我有一個Item類,它有一個不包含setter的可公開訪問的成員NoSetter。該對象顯式聲明一個get,它獲取一個私有隻讀列表對象。內聯列表如何覆蓋沒有setter的屬性?

class Item 
{ 
    private readonly List<string> emptyString; 

    public Item() 
    { 
     this.emptyString = new List<string>(); 
    } 

    public List<string> NoSetter 
    { 
     get { return this.emptyString; } 
    } 
} 

當你創建這個對象,你可以不設置NoSetter到一個列表,當您嘗試編譯失敗。

List<string> goldenString = new List<string>(); 
goldenString.Add("Nope"); 
Item item = new Item() 
{ 
    NoSetter = goldenString 
    // or NoSetter = new List<string>(); 
}; 

但是,如果您創建內聯列表,您可以設置NoSetter。

Item item = new Item() 
{ 
    NoSetter = { "But this still works" } 
}; 

// Outputs: "But this still works" 
Console.WriteLine(item.NoSetter.First<string>()); 

我期望NoSetter.Get方法應該返回只讀列表emptyString,而是返回內聯的NoSetter對象。什麼導致這在.NET中?是否預計?

回答

11

你的第二段代碼不是設置一個新的List<string>,它只是增加它的價值。當應用於集合稱爲Collection Initializer

Item item = new Item(); 
item.NoSetter.Add("But this still works"); 

{...}語法:

Item item = new Item() 
{ 
    NoSetter = { "But this still works" } 
}; 

等效於。從文檔引用(重點介紹):

集合初始化器允許您在初始化實現IEnumerable的集合類時指定一個或多個元素初始化器。元素初始值設定項可以是簡單的值,表達式或對象初始值設定項。 通過使用集合初始值設定項,您不必在源代碼中指定對該類的Add方法的多個調用;編譯器添加這些調用。

+2

This'NoSetter = {「但這仍然有效」}'看起來不像'Add'的語法,你可能是對的,但是有沒有對它的任何引用? – Habib

+0

我拼命尋找......;) –

+0

現在它更有意義。 readonly emptyString不是不可變的,只是不可賦值。 – Joshua