C# InvalidOperationException: Collection Was Modified

Understand InvalidOperationException and solve the collection was modified error.

InvalidOperationException. This exception has occurred. It reports a "collection was modified" error in the program. We are trying to remove elements from a list.

With some code changes, we can fix the problem. It is important to know that the foreach-loop has some restrictions. We cannot change the underlying collection in while foreach is running.Foreach

First example. We see a program that can cause this exception. The example demonstrates a List and a foreach-loop that tries to remove an item, but raises an exception.ExceptionList
Example: We create a List of 3 integers with a list initializer. We then enter a foreach-loop over the list.
Initialize List
Foreach: This loop iterates over each item in the list. We call the Remove method, and it tries to modify the collection during the loop.
C# program that causes InvalidOperationException using System; using System.Collections.Generic; class Program { static void Main() { var list = new List<int>() { 10, 20, 30 }; // Try to remove an element in a foreach list. foreach (int value in list) { Console.WriteLine("ELEMENT: {0}", value); list.Remove(value); } } } Output ELEMENT: 10 Unhandled Exception: System.InvalidOperationException: Collection was modified; enumeration operation may not execute. at System.ThrowHelper. ThrowInvalidOperationException(ExceptionResource resource) at System.Collections. Generic.List`1.Enumerator.MoveNextRare() at System.Collections. Generic.List`1.Enumerator.MoveNext() at Program.Main()...

Notes, Message. Consider the Message property. The Message on the second line is the secret we need to know. The message says "Collection was modified" and that the enumeration won't work.
Note: We are changing the elements in the collection while looping over it with foreach.

Notes, foreach. Foreach queries the enumerator and asks for the next element. In our example, the enumerator's state becomes invalid when we remove the item.
Info: An enumerator has to store some data indicating its current position. This is how the foreach loop is implemented.

Example 2. We see code that removes list elements, without raising an exception. We can call Remove() on the List in a for-loop (with indexes).For
RemoveAt: This is another method we could call. It will accept the index of the item we want to remove—it might be faster.
List Remove
RemoveAll: This might be the best way to remove items from a List without causing an exception. RemoveAll() receives a lambda.
Example: This program removes all elements in the list where the value is equal to 20.
C# program that uses Remove in for-loop using System; using System.Collections.Generic; class Program { static void Main() { var list = new List<int>() { 10, 20, 30 }; // Remove elements from the list in a for-loop. for (int i = 0; i < list.Count; i++) { int value = list[i]; // Remove if value is 20. if (value == 20) { list.Remove(value); } } // Write list after element removed. foreach (int value in list) { Console.WriteLine("ELEMENT: {0}", value); } } } Output ELEMENT: 10 ELEMENT: 30

A summary. An InvalidOperationException is not useful. But the "collection was modified" error message can be informative. RemoveAll can be used to safely remove items from a List.

And with a for-loop, we can remove elements by their indexes. RemoveAt can be used. Alternatively, another new list of elements can be created from the elements we wish to keep.

© 2007-2020 Sam Allen. Every person is special and unique. Send bug reports to info@dotnetperls.com.