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:
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?
One big reason for not allowing modification of a collection while iterating on it is that, if elements in the collection are deleted or if new elements are inserted, it will throw the iteration off. (An element was inserted or deleted right where the iteration is working in the collection; what's the next element now?
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With