Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Going Through A Foreach When It Can Get Modified? [duplicate]

Tags:

c#

foreach

I want to do a foreach loop while taking out members of that foreach loop, but that's throwing errors. My only idea is to create another list inside of this loop to find which Slices to remove, and loop through the new list to remove items from Pizza.

foreach(var Slice in Pizza)
{
    if(Slice.Flavor == "Sausage")
    {
        Me.Eat(Slice); //This removes an item from the list: "Pizza"
    }
}
like image 782
sooprise Avatar asked Jul 12 '10 21:07

sooprise


2 Answers

You can do this, by far the simplest way I have found (like to think I invented it, sure that's not true though ;))

foreach (var Slice in Pizza.ToArray())
{
    if (Slice.Flavor == "Sausage") // each to their own.. would have gone for BBQ
    {
        Me.Eat(Slice);
    }
}

..because it's iterating over a fixed copy of the loop. It will iterate all items, even if they are removed.

Handy isn't it!

(By the way guys, this is a handy way of iterating through a copy of a collection, with thread safety, and removing the time an object is locked: Lock, get the ToArray() copy, release the lock, then iterate)

Hope that helps!

like image 169
Kieren Johnstone Avatar answered Oct 31 '22 23:10

Kieren Johnstone


If you have to iterate through a list and need to remove items, iterate backwards using a for loop:

// taken from Preet Sangha's answer and modified
for(int i = Pizza.Count-1; i >= 0, i--)
{
    var Slice = Pizza[i];
    if(Slice.Flavor == "Sausage")
    {
        Me.Eat(Slice); //This removes an item from the list: "Pizza"
    }
}

The reason to iterate backwards is so that when you remove Elements you don't run into an IndexOutOfRangeException that's caused by accessing Pizza[5] on a Pizza that has only 5 Elements because we removed the sixth one.

The reason to use a for loop is because the iterator variable i has no relation to the Pizza, so you can modify the Pizza without the enumerator "breaking"

like image 28
Michael Stum Avatar answered Oct 31 '22 21:10

Michael Stum