The MoveNext method of an enumerator object encapsulates the code of an iterator block. Invoking the MoveNext method executes code in the iterator block and sets the Current property of the enumerator object as appropriate. The precise action performed by MoveNext depends on the state of the enumerator object when MoveNext is invoked:
If the state of the enumerator object is before, invoking MoveNext:
Changes the state to running.
Initializes the parameters (including this) of the iterator block to the argument values and instance value saved when the enumerator object was initialized.
Executes the iterator block from the beginning until execution is interrupted (as described below).
If the state of the enumerator object is running, the result of invoking MoveNext is unspecified.
If the state of the enumerator object is suspended, invoking MoveNext:
Changes the state to running.
Restores the values of all local variables and parameters (including this) to the values saved when execution of the iterator block was last suspended. Note that the contents of any objects referenced by these variables may have changed since the previous call to MoveNext.
Resumes execution of the iterator block immediately following the yield return statement that caused the suspension of execution and continues until execution is interrupted (as described below).
If the state of the enumerator object is after, invoking MoveNext returns false.
When MoveNext executes the iterator block, execution can be interrupted in four ways: By a yield return statement, by a yield break statement, by encountering the end of the iterator block, and by an exception being thrown and propagated out of the iterator block.
When a yield return statement is encountered (§8.14):
The expression given in the statement is evaluated, implicitly converted to the yield type, and assigned to the Current property of the enumerator object.
Execution of the iterator body is suspended. The values of all local variables and parameters (including this) are saved, as is the location of this yield return statement. If the yield return statement is within one or more try blocks, the associated finally blocks are not executed at this time.
The state of the enumerator object is changed to suspended.
The MoveNext method returns true to its caller, indicating that the iteration successfully advanced to the next value.
When a yield break statement is encountered (§8.14):
If the yield break statement is within one or more try blocks, the associated finally blocks are executed.
The state of the enumerator object is changed to after.
The MoveNext method returns false to its caller, indicating that the iteration is complete.
When the end of the iterator body is encountered:
The state of the enumerator object is changed to after.
The MoveNext method returns false to its caller, indicating that the iteration is complete.
When an exception is thrown and propagated out of the iterator block:
Appropriate finally blocks in the iterator body will have been executed by the exception propagation.
The state of the enumerator object is changed to after.
The exception propagation continues to the caller of the MoveNext method.