If you’ve ever tried to remove an item from a list in C#, you may have encountered the error: “Collection was modified; enumeration may not execute”. Here are two ways that work.
Why you get the error condition
The error happens when using code like this:
List<string> values = new List<string> {"a", "b", "c", "d"}; foreach (string value in values) { if(value == "c") { values.Remove(value); } } Console.WriteLine(values);
The problem is that the code is trying to modify the contents of the “values” List, while it is looping through it.
When the loop starts, the code knows there are four items in this list, and that it is on the first item. If an item is removed from, or added to, the list, that changes the number of items in the list, causing the loop not to be sure where it’s at.
The two-loop method to remove items from a list
The code below lets you remove items from a C# List, by using two loops.
List<string> values = new List<string> { "a", "b", "c", "d" }; // Build new list of values to remove from original list List<string> valuesToRemove = new List<string>(); foreach (string value in values) { if (value == "c") { valuesToRemove.Add(value); } } // Remove the items from the original list foreach (string value in valuesToRemove) { values.Remove(value); } Console.WriteLine(values);
On line 4, we create a new list that will hold items we want to remove from the first (values) List.
On lines 6-12, we loop through the “values” list and add items to delete to the “valuesToRemove” list. This is OK because we are looping through one List and modifying a different List.
Then, on lines 15-18, we loop through the “valuesToRemove” List and remove items from the “values” List. Again, this is OK, because we are looping through one List and modifying a different List.
The predicate method to remove items from a list
A shorter method, and one that eliminates the need for another List variable, is to use the RemoveAll function with a predicate, as in this code:
List<string> values = new List<string> { "a", "b", "c", "d" }; values.RemoveAll(v => v == "c"); Console.WriteLine(values);
The RemoveAll function looks at each item in the List, checks if the condition of the predicate (in this case, does the value equal “c”), and removes the item if the predicate is “true”. If the predicate evaluates to “false”, RemoveAll does not remove the item from the List.
The RemoveAll function is intelligent enough to handle modifying the contents of the List without causing the ” Collection was modified; enumeration may not execute” error.