how is it done?
Trivial. Keep a version counter. Compare version counter when the enumerator was created to the one currently in the enumerated object on every yield. Finished. Obviously: change version on every change.
Now, "i didn't find anything solid" - did it ever occur to you to - ah - read the source code? It is all public, you know...
http://referencesource.microsoft.com/
you look for mscorlib.
FOr example, ArrayList: http://referencesource.microsoft.com/#mscorlib/system/collections/arraylist.cs
It does not get more solid than that.