The collection has been modified; enumeration operation may not be performed in ArrayList

I am trying to remove an element from an ArrayList , and I get this exception:
Collection was modified; enumeration operation may not execute.

Any ideas?

+60
collections c # enumeration exception
Jan 07 '10 at
source share
9 answers

You delete an item during foreach , yes? You just can't. There are several common options here:

  • use List<T> and RemoveAll with predicate
  • iterate back over an index, remove matching items

     for(int i = list.Count - 1; i >= 0; i--) { if({some test}) list.RemoveAt(i); } 
  • use foreach and put matching elements in the second list; now list the second list and remove these elements from the first (if you understand what I mean)

+166
Jan 07 '10 at
source share

Here is 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 are 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, which determines whether the item should be deleted.

+19
Jan 7
source share

One way is to add the items (items) that you want to remove to the new list. Then go through and delete these items.

+8
Jan 07 '10 at
source share

I like to iterate back using a for loop, but it can get tedious compared to foreach . One solution that I like is to create an enumerator that moves the list back. You can implement this as an extension method on an ArrayList or List<T> . The implementation for ArrayList 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> 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 following example uses an 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); } 
+7
Jan 25 2018-11-22T00:
source share

Do not modify the list inside a loop that iterates through the list.

Instead, use for() or while() with the index going backward in the list. (This will allow you to 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 } 
+5
Jan 07 '10 at 22:33
source share

Am I missing something? Someone correct me if I am wrong.

 list.RemoveAll(s => s.Name == "Fred"); 
+4
Jun 07 2018-12-12T00:
source share

Instead of foreach (), use a for () loop with a numeric index.

+2
Jan 07 '10 at
source share

I agree with a few points that I read in this post, and I included them in my solution in order to solve the same problem as the original post.

However, the comments I rated are as follows:

  • "if you are not using .NET 1.0 or 1.1, use List<T> instead of ArrayList ."

  • "Also, add the items you want to remove to the new list. Then execute and delete these items." .. in my case, I just created a new list and populated it with valid data values.

eg.

 private List<string> managedLocationIDList = new List<string>(); string managedLocationIDs = ";1321;1235;;" // user input, should be semicolon seperated list of values managedLocationIDList.AddRange(managedLocationIDs.Split(new char[] { ';' })); List<string> checkLocationIDs = new List<string>(); // Remove any duplicate ID and cleanup the string holding the list if ID's Functions helper = new Functions(); checkLocationIDs = helper.ParseList(managedLocationIDList); ... public List<string> ParseList(List<string> checkList) { List<string> verifiedList = new List<string>(); foreach (string listItem in checkList) if (!verifiedList.Contains(listItem.Trim()) && listItem != string.Empty) verifiedList.Add(listItem.Trim()); verifiedList.Sort(); return verifiedList; } 
+2
Apr 29 '11 at 15:34
source share

using ArrayList you can also try this

 ArrayList arraylist = ... // myobject data list ArrayList temp = (ArrayList)arraylist.Clone(); foreach (var item in temp) { if (...) arraylist.Remove(item); } 
+1
Jun 24 '12 at 7:19
source share



All Articles