2010-11-05 80 views
3

是否有任何指示返回類的對象?我有有一個列表和一個方法,做一些與列表,並返回該列表中的類:C#返回私人對象

public class Foo 
{ 
    private List<Bar> _myList = new List<Bar>(); 

    public List<Bar> DoSomething() 
    { 
    // Add items to the list 
    return _myList; 
    } 

} 

我不認爲這是返回列表的好方法,因爲現在的調用方法可以修改列表,從而更新對象Foo中的列表。這可能會導致意想不到的行爲。

你如何處理這種情況?你做了一個對象的副本(在本例中是列表)並返回該對象,或..?有沒有最佳做法或竅門?

+0

你相信你的來電者做「正確的事」,如果不是在寫一個類的成本變得更多。因此,框架代碼花費更多的時間來編寫應用程序代碼。 – 2010-11-05 10:25:59

回答

7

返回一個新的ReadOnlyCollection

public ReadOnlyCollection<Bar> DoSomething() 
{ 
    // Add items to the list 
    return new ReadOnlyCollection<Bar>(_myList); 
} 

這是清單的包裝和類型是明確一個只讀類型。

作爲@Freed筆記,這不是線程安全的,因爲它只是一個包裝,並且該列表可以在Foo類中更改。如果你想確保集合

public ReadOnlyCollection<Bar> DoSomething() 
{ 
    // Add items to the list 
    return new ReadOnlyCollection<Bar>(new List<Bar>(_myList)); 
} 
+1

但請注意,類本身仍然可以修改集合,導致只讀集合被修改,使其不適合在多線程應用程序中使用。 – SoftMemes 2010-11-05 09:58:00

+0

@freed這就是爲什麼我不喜歡'ReadOnlyCollection ' – 2010-11-05 09:58:52

+2

線程安全還有很多,比如線程安全設計,或者根本就沒有這樣做,開銷並不值得「更線程安全」 – 2010-11-05 10:05:54

2

爲了更好的線程安全,返回它(不過,如果這是一個要求,你應該設計類爲與開始)之前進行復制的元素無法修改,請使用ReadOnlyCollection來傳達此意圖。

或者,您可以實例化新列表並返回新列表中的元素。然後,你的班級不必關心該列表是否被修改。

0

怎麼樣

return new List<Bar>(_myList); 

將這項工作? 對不起 - 太慢;)

1

真正的問題不是關於你的私人_myList的副本,而是將是:你的手還有一些項目的副本?

返回列表的副本,你有幾種選擇

  • ReadOnlyCollection<T>
  • IEnumerable<T>(propably一個真正的轉換,否則攻擊者可以投回到List<T>在外面)
  • 一通過.ToList()
  • 撥打List<T>與私人清單的電話

我不是ReadOnlyCollection<T>的粉絲,因爲它只是剝奪了消費者添加和刪除內容的能力,但與私人列表的連接並未被切斷。所以當你改變你的私人清單時,它會影響那些無用的只讀集合...這可能是一件壞事!

我建議選擇一個選項,其中返回值完全隔離您的內部列表和項目!

+0

「.ToList()」或「List '的構造函數的用法有任何區別嗎? – Martijn 2010-11-05 10:08:31

+0

dunno ...你將不得不測試它與秒錶...其實從來沒有想過... – 2010-11-05 10:11:23

+0

我剛剛經歷,構造函數版本保持參考。當我做'Collection newList = new Collection (_myList);'然後添加一個對象到newList,_myList也會被更新。這怎麼可能? – Martijn 2010-11-05 10:49:45