Reputation: 8681
I know there are lots of ways to do it much better but I've seen it in existing code and now I'm wondering whether or not this could have any negative side effects. Please note the break right after Remove. Therefore I don't care about the iterator in general, however, I do care about unexpected behavior (-> potential exceptions).
foreach (var item in items)
{
//do stuff
if (item.IsSomething)
{
items.Remove(item); //is this safe???
break;
}
}
Could it also be possible the compiler optimizes something in a way I don't expect?
Upvotes: 3
Views: 513
Reputation: 1916
You can't change the list while iterating within foreach.
The underlying collection cannot be modified while it's being enumerated. A standard approach is to keep the items to remove in second list , and then after Items has been enumerated, then remove each item from Items.
Upvotes: 1
Reputation: 2258
then u can do this -- its more efficient when dealing with large lists (Assuming entity framework)
var reducedList = items.where(a=>a.IsSomething).toList();
foreach(var item in reducedList)
{
reducedList.Remove(item);
}
this reduces the foreach
loop iterations
Upvotes: -1
Reputation: 39600
The compiler generates a call to Dispose()
on the enumerator that is executed in a finally
block, but that shouldn't be a problem. If you break
right after removing the item, nothing bad should happen, since you don't use the enumerator anymore.
If you want to do it a different way though (for style reasons or whatever), you could do this:
var item = items.FirstOrDefault(i => i.IsSomething);
if (item != null) {
items.Remove(item);
}
It's also a bit shorter :) (I am assuming here you are using a reference or nullable type in your collection).
Upvotes: 7
Reputation: 4041
The compiler and everything else which is in touch with your application guarantees SC-DRF (sequential consistency for data-race-free programs), so you won't see the difference between the program you wrote and the program which is executed (which is anything but the same). Assuming items
is not shared between multiple threads this is completely safe to write and has no unexpected behaviors others than if you would call Remove
outside the loop.
Upvotes: 2