2011-06-10 49 views
4

我碰到一個方法,通過轉換到一個列表本身這樣的改變在foreach循環列表:在這個foreach循環中創建了垃圾嗎?

foreach (var item in myList.ToList()) 
{ 
    //add or remove items from myList 
} 

(如果你試圖修改myList直接引發錯誤,因爲枚舉基本上將其鎖定)

這是可行的,因爲它不是原來被修改的myList。我的問題是,這是否方法創建garbage當循環結束(即從是一個從ToList方法返回?對於小環的List,那會是最好使用for loop避免垃圾的產生?

+2

是不是推理,至少給了評論「/ /添加或從** myList **刪除項目」?它不應該讀取(longish):「這是因爲它不是'myList',它是**迭代的**(而是使用'ToList()'創建的副本),所以'myList'可以在foreach中修改-循環。「 – 2011-06-10 05:22:20

回答

5

第二個列表將是垃圾,會有針對在建設第二列表中所使用的枚舉的垃圾,並添加枚舉的foreach會催生,你將不得不使用或不第二個列表。

如果您切換到for?也許,如果你可以指向這個區域的代碼是一個真正的性能瓶頸。否則,代碼爲簡單和可維護性。

3

是。ToList()將創建另一個列表,將需要進行垃圾回收。

0

它的不確定性,但是從通話ToList()產生的參考值將是GCD最終。

我不會擔心太多,因爲它最多隻能包含引用或小值類型秒。

1

這是一個有趣的技術,我會牢記未來! (我不敢相信我從來沒有想到這一點!)

無論如何,是的,你正在建設的名單並不神奇地未分配本身。這種技術的可能的性能問題是:

  1. 增加的內存使用(構建List,單獨從IEnumerable)。可能不是那麼重要,除非你經常這樣做,或者IEnumerable非常大。
  2. 降低速度,因爲它必須立即通過IEnumerable來構建List
  3. 此外,如果枚舉IEnumerable有副作用,它們將全部由此過程觸發。

除非這實際上是在一個內部循環中,或者您正在處理非常大的數據集,否則可以毫無問題地執行此操作。

1

是的,ToList()方法創建「垃圾」。我只是索引。

for (int i = MyList.Count - 1; 0 <= i; --i) 
{ 
    var item = MyList[i]; 
    //add or remove items from myList 
} 
+0

我會不停地進行這種優化,直到它顯示出原來的代碼是一個瓶頸,如果不是這樣,那麼讓代碼變得不那麼可讀。 – 2011-06-10 13:56:19