6

给定代码:

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 对象中删除项目的最佳方法吗?

4

3 回答 3

9

我不这么认为。如果您从正在迭代的列表中删除一个项目,结果将是绝对错误的。

最好以相反的顺序使用老式的 for - 循环

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); 
        } 
    } 
}
于 2012-04-14T12:39:34.180 回答
7

循环方法有几个问题,主要是 - 您无法从当前正在迭代的集合中删除项目foreach- 您将遇到异常。

由于您的主要集合是 a List<T>,因此您应该使用RemoveAll接受谓词的方法。您还应该像这样简化查询:

AllItems.RemoveAll(item => !db.tblStoreItems.Any(i => i.ID == item.ItemID));
于 2012-04-14T12:46:13.163 回答
1

正如史蒂夫正确建议的那样(史蒂夫的方式可能是最好的),这是错误的(OP的方法),

我更喜欢将其存储'those to be removed'到一个单独的列表中,然后你可以这样做

AllItems = AllItems.Except(Items2Remove);  

从性能方面来看,这并不是最好的,但对我来说,这会让事情变得更干净——你也可以与 LINQ 枚举结合使用——例如,从记录列表中制作 IEnumerable 等。

希望这有帮助 编辑:只是根据史蒂夫的回应澄清

于 2012-04-14T12:43:33.987 回答