Why this code throws 'Collection was modified', but when I iterate something before it, it doesn't?

C#Collections

C# Problem Overview


var ints = new List< int >( new[ ] {
    1,
    2,
    3,
    4,
    5
} );
var first = true;
foreach( var v in ints ) {
    if ( first ) {
        for ( long i = 0 ; i < int.MaxValue ; ++i ) { //<-- The thing I iterate
            ints.Add( 1 );
            ints.RemoveAt( ints.Count - 1 );
        }
        ints.Add( 6 );
        ints.Add( 7 );
    }
    Console.WriteLine( v );
    first = false;
}

If you comment out the inner for loop, it throws, it's obviously because we did changes to the collection.

Now if you uncomment it, why this loop allow us to add those two items? It takes awhile to run it like half a minute (On Pentium CPU), but it doesn't throw, and the funny thing is that it outputs:

Image

It was a bit of expected, but it indicates that we can change and it actually changes the collection. Any ideas why this behaviour occuring?

C# Solutions


Solution 1 - C#

The problem is that the way that List<T> detects modifications is by keeping a version field, of type int, incrementing it on each modification. Therefore, if you've made exactly some multiple of 232 modifications to the list between iterations, it will render those modifications invisible as far as detection is concerned. (It will overflow from int.MaxValue to int.MinValue and eventually get back to its initial value.)

If you change pretty much anything about your code - add 1 or 3 values rather than 2, or lower the number of iterations of your inner loop by 1, then it will throw an exception as expected.

(This is an implementation detail rather than specified behaviour - and it's an implementation detail which can be observed as a bug in a very rare case. It would be very unusual to see it cause a problem in a real program, however.)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLyingOnTheSkyView Question on Stackoverflow
Solution 1 - C#Jon SkeetView Answer on Stackoverflow