The .NET compiler then creates the necessary IEnumerable- and IEnumerator-implementing classes and the state machine in the background and everything is fine and clear.
Another use case would be to transform an existing List somehow into another List, for example a List<Color> into a List<String>:

But “yield return” becomes dangerous when classes come into play that implement IDisposable. Because now you need to understand what exactly the compiler is doing and if you’ve cut your methods along the right lines. Or if it would be more sensible to not use “yield return” in this case altogether. “Yield return” – like Linq – uses deferred execution, which means that the code in the method isn’t executed when the method is called but rather when the iterator starts its work. But it’s possible that at that moment the IDisposable class is already disposed and the iterator will grasp at nothing

To show what the compiler is actually doing with a “yield return” and why it is relevant how the IDisposable and the iterator are related, I’ve implemented twi sample applications. The first one uses “yield return” and fails at first and then uses it sucessfully. The second one is showing what the compiler is actually doing by me having implemented the IEnumerable and the IEnumerator by myself in the same way the compiler would have done it for “yield return”.

Both programs are identical on the logical level so you can debug where the differences between a working and a faulty “yield return” are.