Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collections while iterating through enumerator

Tags:

c#

.net

When running this code:

var list = new List<string>
{
    "foo",
    "bar",
};

foreach (var l in list)
{
    Console.WriteLine(l);

    list.Add("bar");
}

An exception is thrown:

System.InvalidOperationException: Collection was modified; enumeration operation may not execute.

How does .NET know that the collection is modified while enumerator is iterating that collection? Is there a flag for this in the collection object?

like image 996
vikash sinha Avatar asked May 30 '26 12:05

vikash sinha


1 Answers

A List<T> internally holds its "version" in an integer variable. Each modification to the list (Add, Remove, Sort, Clear, ...) increments this version by one.

Now the enumerator for a List<T>, when initialized, saves this version number. Upon every MoveNext(), i.e. on every iteration, it checks whether the list's version number still equals the saved version number.

This way it can detect when a list is modified between two iterations. Note this implementation causes a peculiar bug with integer overflow: Why this code throws 'Collection was modified', but when I iterate something before it, it doesn't?.

There also appears to be a bug regarding Sort(Comparison<T> comparison), which doesn't increment the version number. This code:

var list = new List<string>
{
    "foo",
    "bar",
};

foreach (var l in list)
{
    Console.WriteLine(l);
    list.Sort((x, y) => x.CompareTo(y));
}

Prints:

foo
foo
like image 84
CodeCaster Avatar answered Jun 02 '26 01:06

CodeCaster