2012-04-14 47 views
6

循環鑑於代碼:如何最好地刪除列表中的項目,在C#

var AllItems = new List<CartItem>(); 

using(var db = new MainContext()) 
{ 
    foreach (var item in AllItems) 
    { 
     if (!db.tblStoreItems.Where(i => i.ID == item.ItemID).Any()) 
     { 
      AllItems.Remove(item); 
     } 
    } 
} 

這是爲了在一個循環中List對象中刪除項目的最佳方式?

回答

7

有幾件事情是錯的循環方式,主要存在的 - 你不能刪除項目從您當前正在迭代的集合中獲得foreach - 您將得到一個異常。

由於您的主要集合是List<T>,因此您應該使用接受謂詞的RemoveAll方法。您還應該像這樣簡化您的查詢:

AllItems.RemoveAll(item => !db.tblStoreItems.Any(i => i.ID == item.ItemID)); 
+1

美麗的謝謝你! – 2012-04-14 13:12:48

9

我不這麼認爲。如果您從正在迭代的列表中刪除一個項目,結果將是安全錯誤的。

最好是使用舊的時尚 - 以相反的順序循環

using(var db = new MainContext()) 
{ 
    for(int x = AllItems.Count - 1; x >= 0; x--) 
    { 
     var item = AllItems[x]; 
     if (!db.tblStoreItems.Where(i => i.ID == item.ItemID).Any()) 
     { 
      AllItems.RemoveAt(x); 
     } 
    } 
} 
+0

非常感謝! – 2012-04-14 12:41:18

+0

正在從數組中刪除項目,並且原始數量的項目正在並行循環。最後它會在'索引超出範圍'時崩潰。 – Pankaj 2012-04-14 12:53:02

1

這是不對的(任擇議定書的做法)爲正確的史蒂夫建議(史蒂夫的方式可能是最好的在性能方面),

我寧願將'those to be removed'存儲在一個單獨的列表中,然後您可以執行例如

AllItems = AllItems.Except(Items2Remove); 

不是從表現方式,但對我來說最好使事情更清潔 - 你也可以使用LINQ列舉相結合 - 例如從記錄等

希望列表中進行了IEnumerable這有助於 編輯:只是爲了澄清按照史蒂夫的響應

+0

@Steve也許我把它'錯了':) - 你是完美的 - 我的意思是'他的方法'。我只是喜歡「圍繞兩次」,你的表現更加卓越,並且工作得很完美。 – NSGaga 2012-04-14 12:46:30