0

I have a list of custom objects named _interestlist. Now I want to remove all the items in this list which have "active" member is set to false. and I wrote some thing like this

      int counter = 0;
        foreach (var interest in _interestlist)
        {
            if (interest.active==false)
            {
                _interestlist.Remove(interest);
            }
            counter++;
        }

But this throws an error like this

Collection was modified; enumeration operation may not execute.

Isn't this operation possible through a loop? IS there any other way to achieve this?

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
None
  • 5,582
  • 21
  • 85
  • 170

6 Answers6

3

As stated above, a foreach loop is using an Enumerator to enumerate your list, which cant be modified while iterating.

You can use LINQ instead:

var count  = _interestList.RemoveAll(x => x.active == false);

Where count is the number of elements removed.

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
2

That is because the foreach uses the GetEnumerator function. That enumerator will invalidate on changing (adding, removing, etc) the collection.

As suggested, use for instead.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
1

You can't modify the collection you are iterating in foreach loop, use the for instead:

for (int counter = _interestlist.Count - 1; i >= 0; counter--)
{
    if (!interest[counter].active)
    {
        _interestlist.Remove(interest[counter]);
    }
}

Also, you shouldn't check your bool field like this:

if (!interest.active)
VMAtm
  • 27,943
  • 17
  • 79
  • 125
  • 1
    This will not work. If you need to remove elements then you must iterate backwards so you can remove elements from the end of the list. – HABJAN Apr 26 '14 at 09:53
  • @HABJAN Updated the code, thanks. But you can simply do `counter--` in case of removal. – VMAtm Apr 26 '14 at 09:55
1

The standard approach is to keep track of the items to remove (e.g., in another list), and then after Items has been enumerated, enumerate the removelist, removing each item from Items.

HABJAN
  • 9,212
  • 3
  • 35
  • 59
1

Iterating through a list using foreach statement looks like

IEnumerator enumerator = list.GetEnumerator();

while ( enumerator.MoveNext() )
{
    Console.WriteLine( enumerator.Current );
}

You can observe that you use the same object that you got before iterating that's why you cant modify iterated list elements in foreach statement

Adrian
  • 693
  • 5
  • 19
0

No You can not modify the Enumerators because they are Read-Only

From MSDN : GetEnumerator()

Enumerators can be used to read the data in the collection, but they cannot be used to modify the underlying collection.

Solution : One solution is to iterate the items from the last to first for removing the required items.

Try This:

for (int i= _interestlist.Count-1; i >= 0 ;i--)
{
    if (_interestlist[i].active == false)
    {
        _interestlist.Remove(_interestlist[i]);
    }       
}
Sudhakar Tillapudi
  • 25,935
  • 5
  • 37
  • 67