2012-04-14 12 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

美しいありがとう! –

9

私はそうは思わない。反復処理中のリストから項目を削除すると、結果は間違っています。

それはのために古いファッションを使用するのが最善です - 逆の順番でループ

として当然のスティーブによって提案された(OPのアプローチ)間違っている
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

恐縮です! –

+0

アイテムは配列から削除されており、元のアイテム数に対して平行ループが実行されています。最後に 'Index Out of Range'でクラッシュします。 – Pankaj

1

(スティーブの方法は、パフォーマンスの面でおそらく最高です)

'those to be removed'を別のリストに保存することをお勧めします。パフォーマンスの途中からではなく、私は物事がきれいになりための最善ではありません

AllItems = AllItems.Except(Items2Remove); 

- 例えば - あなたはまた、列挙LINQと組み合わせることができレコードのリストからIEnumerableを作るなど

希望これは EDITを支援します。スティーブの応答

+0

@Steve多分私はそれを「間違って」置いています:)あなたのものは完璧です。私は彼のアプローチを意味しました。私はちょうど2倍の周りに行くことを好む、あなたのより多くのperformantと完璧に動作します。 – NSGaga

関連する問題