The compiler generates the final machine on your behalf.
From the language specification:
10.14 Iterators
10.14.4 Enumerator Objects
When a member of a function returns an enumerator interface type implemented using an iterator block, calling the function element does not immediately execute code in the iterator block. Instead, an enumerator object is created and returned. This object encapsulates the specified code in the iterator block and code execution in the iterator block occurs when enumerator objects MoveNext method is called. The enumerator object has the following characteristics:
β’ It implements IEnumerator and IEnumerator, where T is the output type of the iterator.
β’ It implements System.IDisposable.
β’ It is initialized with a copy of the argument value (if any) and an instance of the value passed to the function member.
β’ It has four potential states, before, running, paused and after, and is initially in the before state.
An enumerator object is usually an instance of an compiler-generated enumeration class that encapsulates code in an iterator block and implements enumerator interfaces, but other implementation methods are possible. If the class of the enumerator is generated by the compiler, that the class will be nested, directly or indirectly, in the class containing the member of the function, it will have private access, and this will have a name reserved for use by the compiler (Β§2.4.2).
To understand this, here is how Reflector decompiles your class:
public class EnumeratorExample { // Methods public static IEnumerable<int> GetSource(int startPoint) { return new <GetSource>d__0(-2) { <>3__startPoint = startPoint }; } // Nested Types [CompilerGenerated] private sealed class <GetSource>d__0 : IEnumerable<int>, IEnumerable, IEnumerator<int>, IEnumerator, IDisposable { // Fields private int <>1__state; private int <>2__current; public int <>3__startPoint; private int <>l__initialThreadId; public int <index>5__3; public bool <keepSearching>5__2; public int[] <values>5__1; public int startPoint; // Methods [DebuggerHidden] public <GetSource>d__0(int <>1__state) { this.<>1__state = <>1__state; this.<>l__initialThreadId = Thread.CurrentThread.ManagedThreadId; } private bool MoveNext() { switch (this.<>1__state) { case 0: this.<>1__state = -1; this.<values>5__1 = new int[] { 1, 2, 3, 4, 5, 6, 7 }; this.<keepSearching>5__2 = true; this.<index>5__3 = this.startPoint; while (this.<keepSearching>5__2) { this.<>2__current = this.<values>5__1[this.<index>5__3]; this.<>1__state = 1; return true; Label_0073: this.<>1__state = -1; this.<index>5__3++; this.<keepSearching>5__2 = this.<index>5__3 < this.<values>5__1.Length; } break; case 1: goto Label_0073; } return false; } [DebuggerHidden] IEnumerator<int> IEnumerable<int>.GetEnumerator() { EnumeratorExample.<GetSource>d__0 d__; if ((Thread.CurrentThread.ManagedThreadId == this.<>l__initialThreadId) && (this.<>1__state == -2)) { this.<>1__state = 0; d__ = this; } else { d__ = new EnumeratorExample.<GetSource>d__0(0); } d__.startPoint = this.<>3__startPoint; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return this.System.Collections.Generic.IEnumerable<System.Int32>.GetEnumerator(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } void IDisposable.Dispose() { } // Properties int IEnumerator<int>.Current { [DebuggerHidden] get { return this.<>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return this.<>2__current; } } } }