从通用List<t>中删除项目

9

我有以下方法,希望从我的集合中删除与产品ID匹配的项目。看起来很简单,但我遇到了异常。基本上,我的集合已经失去同步。那么,从集合中删除项目的最佳方法是什么。

public void RemoveOrderItem(Model.Order currentOrder, int productId)
{

    foreach (var orderItem in currentOrder.OrderItems)
    {
        if (orderItem.Product.Id == productId)
        {
            currentOrder.OrderItems.Remove(orderItem);
        }
    }
}

异常细节:System.InvalidOperationException: 集合已修改;枚举操作无法执行
6个回答

29

在循环内修改集合是无效的。为了解决这个问题,List 提供了一些允许“批量”修改集合的方法。在你的情况下,请使用:

currentOrder.OrderItems.RemoveAll(x => x.Product.Id == productId)

谢谢Conrad,奇怪的是我无法让lambda函数工作。它无法识别“x.Product.Id”部分。很奇怪,因为以下代码可以正常工作: var query = from x in currentOrder.OrderItems where x.Product.Id == productId select x; 集合类型是ISet。 - frosty
好的,我回答了自己的问题 :) 我已经将其更改为List<t>。 - frosty

5
你不能在迭代集合时修改它。使用普通的 for 循环而不是 foreach 循环即可。

这对我来说是最好的解决方案。 - EagleFox

3

通过这种方式循环,您无法删除项目,因为它在集合中保持存储的项目跟踪。

更简单的方法:

   authorsList.RemoveAll(x => x.ProductId == productId);

或者

   authorsList = authorsList.Where(x => x.ProductId!= productId).ToList();

2

在迭代集合时,您无法从中删除项目,您可以跟踪orderItem的顺序,然后在完成循环后将其删除。


1

正如您所意识到的那样,在循环遍历集合时无法删除其中的项。我相信有人能够提供更简洁的LINQ解决方案,但以下内容应该可以帮助您开始:

public void RemoveOrderItem(Model.Order currentOrder, int productId)
{
    var selectedOrderItem = null;
    foreach (var orderItem in currentOrder.OrderItems)
    {
        if (orderItem.Product.Id == productId)
        {
            selectedOrderItem = orderItem;
            break;
        }
    }

    if(selectedOrderItem != null)
        currentOrder.OrderItems.Remove(selectedOrderItem);
}

Konrad Rudolph 提供了 LINQ 解决方案。 - openshac
请注意,List<T>.RemoveAll 在 .NET 2.0 中可用,技术上不属于 LINQ,尽管它看起来很相似。对于那些必须保持与 Windows 2000 兼容性的可怜人来说,这是一个巨大的优势,胜过了 LINQ。 - OregonGhost

0
"

"foreach"提供了一个“只向前只读”的集合迭代。

作为一种解决方法,您可以将引用复制到另一个集合中,然后在复制的集合上进行迭代,并从原始集合中删除项目。

"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接