2015-10-19 38 views
2

我有一些遺留的C#代碼與下面的一段:的AddRange讓步公共訪問列表

private List<MyClass> mList = new List<MyClass>(); 

public List<MyClass> getList() 
{ 
    List<MyClass> list = new List<MyClass>(); 
    list.AddRange(mList); 
    return list; 
} 

不知道是什麼的AddRange這裏的目的是什麼?我可以把它改寫爲:

public List<MyClass> getList() 
{ 
    return mList; 
} 
+3

是的。從顯示的代碼中,應該足夠了。 –

+4

不完全相同,因爲'getList'使用相同的對象創建一個新列表,而'return mList'返回甚至相同的列表。所以如果你要調用getList()。Clear()',原始列表也會被清除。 –

+0

此屬性具有醜陋的副作用,因爲它意味着您可以通過修改返回的列表來更改擁有類的狀態。返回一個「IEnumerable」或者將其作爲一種方法是合適的。 – Silvermind

回答

5

如果單純使用return mlist,你返回mlist實例,而原來的代碼返回它的一個淺拷貝。


說你的類如下所示:

class Foo 
{ 
    public Foo() 
    { 
     mList.Add(1); 
    } 

    private List<int> mList = new List<int>(); 

    public List<int> getList() 
    { 
     List<int> list = new List<int>(); 
     list.AddRange(mList); 
     return list; 
    } 
} 

現在你運行

var x = new Foo(); 
x.getList().Add(2); 
x.getList().Add(3); 

mList內容仍然是一個1,因爲getList調用返回副本mList,而不是列表本身。

如果更改就像你在你的問題做了代碼,你會改變mList現在將包含的元素123


這不是從一個副本返回方法的名稱清楚,所以你也許希望將它更改爲類似GetListCopy(在這種情況下,該方法可以簡單地返回new List<MyClass>(mList)mList.ToList()),或返回列表,一個IReadOnlyList表明不應該更改列表。

public IReadOnlyCollection<MyClass> getList() 
{ 
    return mList.AsReadOnly(); 
} 
+1

這個沒啥解釋 –

+0

@TimSchmelter你覺得怎麼解釋不了?原始代碼返回列表的副本,新代碼返回'mList'實例。 – sloth

+2

OP似乎並不熟悉C#並提出一個基本問題。因此,回答它返回一個淺拷貝而不是原始列表可能是正確的,但如果OP不知道它的意思,它不是很有幫助。何時重要/有所作爲? (如果你調用Clear()') –

0

不,你不能。 這可能會導致您的軟件出現一些意外行爲,因爲代碼就像創建一個List的新實例,並且您的解決方案每次調用該方法時都會返回相同的實例。

2

正如已經指出的那樣,如果您只使用return mList;它將返回原始列表而不是其副本。

但是你可以用它簡化:

public List<MyClass> getList 
{ 
    return mList.ToList(); // returns copy of original list 
} 
0

這裏的唯一目的是克隆原來的列表,以保持不變。 不過,最好是重新寫此屬性,並把它轉化爲方法:在源IEnumerable<T>

public List<MyClass> getList() 
{ 
    // note, that Enumerable.ToList() does the same 
    return new List(mList); 
} 

List<T>構造檢查ICollection<T>實施,並正確地設置初始容量。由於每次調用都會創建新實例,因此這不應該是屬性,而應該是一種方法。

0

蒂姆的評論和懶惰的已經給出了正確的解釋。

只是一個額外的點:

private List<MyClass> mList = new List<MyClass>(); 

public List<MyClass> getList1() 
{ 
    List<MyClass> list = new List<MyClass>(); 
    list.AddRange(mList); 
    return list; 
} 

public List<MyClass> getList2() 
{ 
    return mList; 
} 

getlis1() -
(1)保持原始列表安全Add()AddRange()Clear()不會影響它。
(2)拋出如果mList爲空,則爲異常!

getlis2() -
(1)公開原始列表mListAdd()AddRange()Clear()影響(修改)它。
(2)如果mList爲空,則返回null