frosty
frosty

Reputation: 5370

removing items from a generic List<t>

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

Upvotes: 9

Views: 11918

Answers (6)

Manish Basantani
Manish Basantani

Reputation: 17499

"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.

Upvotes: 0

Pranay Rana
Pranay Rana

Reputation: 176896

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

Upvotes: 3

openshac
openshac

Reputation: 5155

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

Upvotes: 1

BenW
BenW

Reputation: 1312

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

Upvotes: 2

Hans Olsson
Hans Olsson

Reputation: 54999

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

Upvotes: 5

Konrad Rudolph
Konrad Rudolph

Reputation: 545528

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)

Upvotes: 29

Related Questions