![]()
The System.InvalidOperationException – Collection was modified; enumeration operation may not execute is a runtime exception in C# that occurs when you modify a collection (e.g., add, remove, or update elements) while enumerating over it using a foreach loop or an enumerator. This typically happens when:
- You modify the collection (e.g., add or remove elements) while iterating over it.
- You use an enumerator that becomes invalid after the collection is modified.
Here’s how you can troubleshoot and fix this issue:
1. Avoid Modifying Collections During Enumeration
- Do not modify the collection (e.g., add, remove, or update elements) while iterating over it. Example:
List<int> numbers = new List<int> { 1, 2, 3 };
foreach (int number in numbers)
{
if (number == 2)
{
numbers.Remove(number); // Error: Collection was modified
}
}
Fix:
List<int> numbers = new List<int> { 1, 2, 3 };
for (int i = numbers.Count - 1; i >= 0; i--) // Iterate backward to safely remove elements
{
if (numbers[i] == 2)
{
numbers.RemoveAt(i); // Safe: Modify collection outside of enumeration
}
}
2. Use a Copy of the Collection
- Create a copy of the collection and iterate over the copy while modifying the original collection. Example:
List<int> numbers = new List<int> { 1, 2, 3 };
foreach (int number in numbers.ToList()) // Create a copy of the list
{
if (number == 2)
{
numbers.Remove(number); // Safe: Modify original collection
}
}
3. Use a Separate Collection for Modifications
- Store the elements to be modified in a separate collection and apply the changes after the enumeration. Example:
List<int> numbers = new List<int> { 1, 2, 3 };
List<int> toRemove = new List<int>();
foreach (int number in numbers)
{
if (number == 2)
{
toRemove.Add(number); // Store elements to remove
}
}
foreach (int number in toRemove)
{
numbers.Remove(number); // Modify collection after enumeration
}
4. Use for Loops Instead of foreach
- Use a
forloop to iterate over the collection and modify it safely. Example:
List<int> numbers = new List<int> { 1, 2, 3 };
for (int i = 0; i < numbers.Count; i++)
{
if (numbers[i] == 2)
{
numbers.RemoveAt(i); // Safe: Modify collection using index
i--; // Adjust index after removal
}
}
Example of Correct Code
using System;
using System.Collections.Generic;
public class Program
{
public static void Main(string[] args)
{
// Example 1: Avoid modifying collections during enumeration
List<int> numbers = new List<int> { 1, 2, 3 };
for (int i = numbers.Count - 1; i >= 0; i--) // Iterate backward
{
if (numbers[i] == 2)
{
numbers.RemoveAt(i); // Safe: Modify collection outside of enumeration
}
}
Console.WriteLine(string.Join(", ", numbers)); // Output: 1, 3
// Example 2: Use a copy of the collection
List<int> numbers2 = new List<int> { 1, 2, 3 };
foreach (int number in numbers2.ToList()) // Create a copy
{
if (number == 2)
{
numbers2.Remove(number); // Safe: Modify original collection
}
}
Console.WriteLine(string.Join(", ", numbers2)); // Output: 1, 3
// Example 3: Use a separate collection for modifications
List<int> numbers3 = new List<int> { 1, 2, 3 };
List<int> toRemove = new List<int>();
foreach (int number in numbers3)
{
if (number == 2)
{
toRemove.Add(number); // Store elements to remove
}
}
foreach (int number in toRemove)
{
numbers3.Remove(number); // Modify collection after enumeration
}
Console.WriteLine(string.Join(", ", numbers3)); // Output: 1, 3
// Example 4: Use 'for' loops instead of 'foreach'
List<int> numbers4 = new List<int> { 1, 2, 3 };
for (int i = 0; i < numbers4.Count; i++)
{
if (numbers4[i] == 2)
{
numbers4.RemoveAt(i); // Safe: Modify collection using index
i--; // Adjust index after removal
}
}
Console.WriteLine(string.Join(", ", numbers4)); // Output: 1, 3
}
}
