2016-09-05 83 views
1

值我想到了一個非常簡潔的方式,用於訪問列表屬性:列表與後盾屬性不會被添加在

private List<int> _stages; 
public List<int> Stages 
{ 
    get 
    { 
     return (_stages ?? (_stages = new List<int>())).OrderBy(s => s).ToList(); 
    } 
    set 
    { 
     _stages = value; 
    } 
} 

這樣即使Stages爲空,如果我用Stages.Add(1)它會被初始化首先,然後添加值。然而,它不起作用,我真的不知道,因爲沒有太多的調試。 _stages獲得初始化,但無論我多次呼叫Stages.Add(1)_stages仍然是一個空列表。

我錯過了什麼?

回答

3
return (_stages ?? (_stages = new List<int>())).OrderBy(s => s).ToList(); 

最終這相當於這個:

var stages = _stages; 
if (stages == null) 
    stages = _stages = new List<int>(); 

return stages.OrderBy(s => s).ToList(); 

所以,當你正確初始化列表時,它是空,你還在總是返回.OrderBy(s => s).ToList()

Enumerable.ToList()致電將總是創建一個新的列表。

所以由getter返回的列表是一個新的列表,它沒有鏈接到內部支持的_stages列表。所以,當你添加一個項目到列表中時,你將它添加到排序後的副本中,而不是原始列表中。

您可以通過將排序後的列表隨時分配回支持字段來改變這一點,但是這仍然會導致在您訪問屬性時總是對字段進行排序的開銷。一般來說,訪問getter不應該有副作用,所以我會避免這樣做。最好在對象上提供一個明確的SortStages方法來實際排序列表。

此外,您應該考慮使用List.Sort()就地對列表進行排序,因此您最終不會得到新的列表對象。

+0

是的,'List.Sort()'是我嘗試實現的,但是使用了導致我的錯誤的錯誤工具。謝謝! –

2

通過做ToList()你正在返回一個新的列表。如果您在調用它Add,它不會在_stages

+0

我知道我錯過了一些非常小但非常重要的東西!謝謝! –