Question:
As you know, if during the foreach
collection that it iterates over will be changed (in another thread, for example), then an exception will occur. But how does this exception mechanism work? Who is responsible for detecting the change? Should I take steps to support this behavior when designing my collections, or will things always start out of the box ?
Answer:
The foreach
equivalent to roughly the following code:
int[] a = { 1, 2, 3, 4 };
var enumerator = ((IEnumerable<int>)a).GetEnumerator();
while (enumerator.MoveNext())
{
var item = enumerator.Current;
// ... тело цикла ...
}
Thus, it all depends on the implementation of the IEnumerable<T>.GetEnumerator()
method in a particular collection.
For most of the .Net built-in collections, this method returns a class that keeps version
collection's private version
property. Which in turn increases by 1 every time the collection changes.
Except for one bug, which I already wrote about in Microsoft, but it didn’t make sense. The List<T>.Sort(Comparison<T> comparison)
method does not invoke a version increment.