removing items from a generic List

2020-06-03 07:28发布

问题:

I have the following method, I wish to remove items from my collection that match the product Id. Seems fairly straight forward, but i get an exception. Basically my collection is getting out of sync. So what is the best way to remove an item from a collection.

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

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

Exception Details: System.InvalidOperationException: Collection was modified; enumeration operation may not execute

回答1:

Modifying a collection inside a loop doesn’t work. To work around that, List has a few methods that allow “batch” modifications of a collection. In your case, use:

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


回答2:

You can't modify a collection while iterating it. Just use a normal for loop instead of a foreach loop.



回答3:

By looping this way you can not remove items because its in collection it keeps the track of the stored items.

Easy way to do this :

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

or

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


回答4:

You can't remove an item from a collection you are iterating through, you could keep track of the orderItem, then remove it after you finish looping



回答5:

As you realise you can't remove an item from a collection whilst you are looping over it. I'm sure someone will be able to provided a neater LINQ solution but the following should get you going initially:

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);
}


回答6:

"foreach" provides a "Forward-only read-only" iteration of a collection.

As a workaround, you can copy the reference to another collection and then iterate on the copied collection and remove the items from the original one.