C# 从常规列表中删除项目<;t>;

C# 从常规列表中删除项目<;t>;,c#,linq,generics,list,C#,Linq,Generics,List,我有下面的方法,我希望从我的集合中删除与产品Id匹配的项目。看起来很简单,但我得到了一个例外。基本上我的收藏已经不同步了。那么,从集合中删除项目的最佳方式是什么呢 public void RemoveOrderItem(Model.Order currentOrder, int productId) { foreach (var orderItem in currentOrder.OrderItems) { if (orderItem.Product.Id ==

我有下面的方法,我希望从我的集合中删除与产品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:集合已修改;枚举操作可能不会执行

在循环中修改集合不起作用。为了解决这个问题,
List
有一些方法允许对集合进行“批量”修改。在您的情况下,请使用:

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

您不能在迭代集合时对其进行修改。只需使用普通的
for
循环,而不是
foreach
循环。

您不能从正在迭代的集合中删除项目,您可以跟踪orderItem,然后在完成循环后将其删除

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

实现这一点的简单方法:

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


当你意识到你不能从一个集合中删除一个项目,而你是在它上面循环。我相信有人能够提供一个更整洁的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);
}
“foreach”提供集合的“仅向前只读”迭代


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

Konrad Rudolph提供了LINQ解决方案注意,
List.RemoveAll
在.NET 2.0中可用,技术上与LINQ不同,尽管它看起来类似。对于那些必须保持Windows 2000兼容性的可怜人来说,这比LINQ有很大的好处。谢谢康拉德,奇怪的是,我无法让lamda正常工作。它无法识别“x.Product.Id”部分。奇怪的是,在currentOrder.OrderItems中,下面的works var query=from x,其中x.Product.Id==productId选择x;集合类型是ISet。好的,我回答了我自己的问题:)我已将此更改为列表:)这是我的最佳解决方案
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);
}