Why the error Collection was modified; enumeration operation may not execute occurs and how to handle it in C#?

This error occurs when you modify a collection (such as adding or removing items) while iterating through it with a foreach loop or enumerator. The .NET runtime throws this exception to prevent unpredictable behavior and maintain collection integrity.

Why This Error Occurs

When you use foreach, it creates an internal enumerator that tracks the collection's state. If the collection is modified during iteration, the enumerator detects this change and throws an InvalidOperationException to prevent data corruption or infinite loops.

Collection Modification During Iteration Original Collection: [Item1, Item2, Item3] foreach starts iteration Item2 removed Exception thrown! Enumerator detects modification and prevents corruption

Example Demonstrating the Error

The following example shows how this error occurs when removing items during iteration −

using System;
using System.Collections.Generic;

namespace DemoApplication {
    public class Program {
        static void Main(string[] args) {
            try {
                var studentsList = new List<Student> {
                    new Student {
                        Id = 1,
                        Name = "John"
                    },
                    new Student {
                        Id = 0,
                        Name = "Jack"
                    },
                    new Student {
                        Id = 2,
                        Name = "Jane"
                    }
                };
                foreach (var student in studentsList) {
                    if (student.Id <= 0) {
                        studentsList.Remove(student);
                    }
                    else {
                        Console.WriteLine($"Id: {student.Id}, Name: {student.Name}");
                    }
                }
            }
            catch(Exception ex) {
                Console.WriteLine($"Exception: {ex.Message}");
            }
        }
    }
    
    public class Student {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

The output of the above code is −

Id: 1, Name: John
Exception: Collection was modified; enumeration operation may not execute.

Solution Methods

Using ToList() to Create a Copy

Create a snapshot of the collection using ToList() before iteration. This allows you to modify the original collection safely −

using System;
using System.Collections.Generic;
using System.Linq;

namespace DemoApplication {
    public class Program {
        static void Main(string[] args) {
            var studentsList = new List<Student> {
                new Student {
                    Id = 1,
                    Name = "John"
                },
                new Student {
                    Id = 0,
                    Name = "Jack"
                },
                new Student {
                    Id = 2,
                    Name = "Jane"
                }
            };
            
            foreach (var student in studentsList.ToList()) {
                if (student.Id <= 0) {
                    studentsList.Remove(student);
                }
                else {
                    Console.WriteLine($"Id: {student.Id}, Name: {student.Name}");
                }
            }
            
            Console.WriteLine($"Remaining students: {studentsList.Count}");
        }
    }
    
    public class Student {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

The output of the above code is −

Id: 1, Name: John
Id: 2, Name: Jane
Remaining students: 2

Using RemoveAll() Method

For removal scenarios, use the RemoveAll() method which is designed to handle modifications safely −

using System;
using System.Collections.Generic;

namespace DemoApplication {
    public class Program {
        static void Main(string[] args) {
            var studentsList = new List<Student> {
                new Student { Id = 1, Name = "John" },
                new Student { Id = 0, Name = "Jack" },
                new Student { Id = 2, Name = "Jane" },
                new Student { Id = -1, Name = "Invalid" }
            };
            
            Console.WriteLine("Before removal:");
            foreach (var student in studentsList) {
                Console.WriteLine($"Id: {student.Id}, Name: {student.Name}");
            }
            
            int removedCount = studentsList.RemoveAll(s => s.Id <= 0);
            
            Console.WriteLine($"\nRemoved {removedCount} students");
            Console.WriteLine("After removal:");
            foreach (var student in studentsList) {
                Console.WriteLine($"Id: {student.Id}, Name: {student.Name}");
            }
        }
    }
    
    public class Student {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

The output of the above code is −

Before removal:
Id: 1, Name: John
Id: 0, Name: Jack
Id: 2, Name: Jane
Id: -1, Name: Invalid
Removed 2 students
After removal:
Id: 1, Name: John
Id: 2, Name: Jane

Using For Loop (Reverse Iteration)

When removing items, iterate backwards using a traditional for loop to avoid index shifting issues −

using System;
using System.Collections.Generic;

namespace DemoApplication {
    public class Program {
        static void Main(string[] args) {
            var studentsList = new List<Student> {
                new Student { Id = 1, Name = "John" },
                new Student { Id = 0, Name = "Jack" },
                new Student { Id = 2, Name = "Jane" }
            };
            
            for (int i = studentsList.Count - 1; i >= 0; i--) {
                if (studentsList[i].Id <= 0) {
                    Console.WriteLine($"Removing: {studentsList[i].Name}");
                    studentsList.RemoveAt(i);
                }
                else {
                    Console.WriteLine($"Keeping: Id: {studentsList[i].Id}, Name: {studentsList[i].Name}");
                }
            }
            
            Console.WriteLine($"Final count: {studentsList.Count}");
        }
    }
    
    public class Student {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

The output of the above code is −

Keeping: Id: 2, Name: Jane
Removing: Jack
Keeping: Id: 1, Name: John
Final count: 2

Best Practices

Scenario Recommended Solution Performance
Removing items based on condition RemoveAll() method Best
Complex modifications during iteration ToList() copy Good
Index-based removal Reverse for loop Good
Adding items during iteration Collect items, add after loop Best

Conclusion

The "Collection was modified" error protects against data corruption during iteration. Use RemoveAll() for conditional removal, ToList() for complex modifications, or reverse iteration for index-based operations. Choose the method that best fits your specific use case for optimal performance and code clarity.

Updated on: 2026-03-17T07:04:36+05:30

21K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements