I'm trying to remove an item from an ArrayList and I get this Exception:
Collection was modified; enumeration operation may not execute.
Any ideas?
I'm trying to remove an item from an ArrayList and I get this Exception:
Collection was modified; enumeration operation may not execute.
Any ideas?
You are removing the item during a foreach, yes? Simply, you can't. There are a few common options here:
List<T> and RemoveAll with a predicateiterate backwards by index, removing matching items
for(int i = list.Count - 1; i >= 0; i--) {
if({some test}) list.RemoveAt(i);
}
use foreach, and put matching items into a second list; now enumerate the second list and remove those items from the first (if you see what I mean)
Here's an example (sorry for any typos)
var itemsToRemove = new ArrayList(); // should use generic List if you can
foreach (var item in originalArrayList) {
if (...) {
itemsToRemove.Add(item);
}
}
foreach (var item in itemsToRemove) {
originalArrayList.Remove(item);
}
OR if you're using 3.5, Linq makes the first bit easier:
itemsToRemove = originalArrayList
.Where(item => ...)
.ToArray();
foreach (var item in itemsToRemove) {
originalArrayList.Remove(item);
}
Replace "..." with your condition that determines if item should be removed.
One way is to add the item(s) to be deleted to a new list. Then go through and delete those items.
I like to iterate backward using a for loop, but this can get tedious compared to foreach. One solution I like is to create an enumerator that traverses the list backward. You can implement this as an extension method on ArrayList or List<T>. The implementation for ArrayList is below.
public static IEnumerable GetRemoveSafeEnumerator(this ArrayList list)
{
for (int i = list.Count - 1; i >= 0; i--)
{
// Reset the value of i if it is invalid.
// This occurs when more than one item
// is removed from the list during the enumeration.
if (i >= list.Count)
{
if (list.Count == 0)
yield break;
i = list.Count - 1;
}
yield return list[i];
}
}
The implementation for List<T> is similar.
public static IEnumerable<T> GetRemoveSafeEnumerator<T>(this List<T> list)
{
for (int i = list.Count - 1; i >= 0; i--)
{
// Reset the value of i if it is invalid.
// This occurs when more than one item
// is removed from the list during the enumeration.
if (i >= list.Count)
{
if (list.Count == 0)
yield break;
i = list.Count - 1;
}
yield return list[i];
}
}
The example below uses the enumerator to remove all even integers from an ArrayList.
ArrayList list = new ArrayList() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
foreach (int item in list.GetRemoveSafeEnumerator())
{
if (item % 2 == 0)
list.Remove(item);
}
Don't modify the list inside of a loop which iterates through the list.
Instead, use a for() or while() with an index, going backwards through the list. (This will let you delete things without getting an invalid index.)
var foo = new List<Bar>();
for(int i = foo.Count-1; i >= 0; --i)
{
var item = foo[i];
// do something with item
}