【问题标题】:How best to remove list items in a loop in C#如何最好地在 C# 中的循环中删除列表项
【发布时间】:2012-04-26 13:48:14
【问题描述】:

给定代码:

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

【问题讨论】:

    标签: c# asp.net list loops


    【解决方案1】:

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

    最好使用老式的 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); 
            } 
        } 
    }
    

    【讨论】:

    • 项目正在从数组中删除,并且对原始项目数量进行并行循环。最后它会在Index Out of Range崩溃。
    【解决方案2】:

    这是错误的(OP 的方法),正如 Steve 正确建议的那样(就性能而言,Steve 的方法可能是最好的),

    我更喜欢将'those to be removed' 存储到单独的列表中,然后您可以执行例如

    AllItems = AllItems.Except(Items2Remove);  
    

    这不是最好的性能方式,但对我来说让事情更清洁 - 你也可以与 LINQ 枚举结合使用 - 例如从记录列表等中使 IEnumerable 成为可能。

    希望这会有所帮助 编辑:根据史蒂夫的回应澄清一下

    【讨论】:

    • @Steve 也许我说错了 :) - 你的很完美 - 我的意思是“他的方法”。我只是更喜欢“两次”,你的性能更好,而且效果很好。
    【解决方案3】:

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

    由于您的主要集合是List&lt;T&gt;,您应该使用接受谓词的RemoveAll 方法。您还应该像这样简化查询:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-26
      • 1970-01-01
      • 1970-01-01
      • 2012-01-08
      相关资源
      最近更新 更多