MoveNext

Метод MoveNext объекта перечислителя инкапсулирует код блока итератора. При вызове метода MoveNext выполняется код в блоке итератора и устанавливается соответствующее свойство Current объекта перечислителя. Точное действие, выполняемое MoveNext, зависит от состояния объекта перечислителя при вызове MoveNext:

· Если состояние объекта перечислителя before, то при вызове MoveNext:

o состояние меняется на running;

o инициализируются параметры (включая this) блока итератора значениями аргументов и значением экземпляра, сохраненными при инициализации объекта перечислителя;

o выполняется блок итератора от начала и до тех пор, пока выполнение не будет прервано (как описано ниже).

· Если состояние объекта перечислителя running, результат вызова MoveNext не определен.

· Если состояние объекта перечислителя suspended, при вызове MoveNext:

o состояние меняется на running;

o восстанавливаются значения всех локальных переменных и параметров (включая this) к значениям, сохраненным при последней приостановке выполнения блока итератора. Обратите внимание, что содержимое любых объектов, на которые ссылаются эти переменные, могло измениться со времени предыдущего вызова MoveNext;

o возобновляется выполнение блока итератора с оператора, непосредственно следующего за оператором yield return, вызвавшим приостановку выполнения, и продолжается до тех пор, пока выполнение не будет прервано (как описано ниже).

· Если состояние объекта перечислителя after, при вызове MoveNext возвращается false.

Когда MoveNext выполняет блок итератора, выполнение может быть прервано четырьмя способами: оператором yield return, оператором yield break, по концу блока итератора и инициированным исключением, распространенным из блока итератора.

· Если встретился оператор yield return (§8.14):

o выражение, заданное в операторе, вычисляется, неявно преобразуется к типу yield и присваивается свойству Current объекта перечислителя;

o выполнение тела итератора приостанавливается. Значения всех локальных переменных и параметров (включая this) сохраняются, как и место этого оператора yield return. Если оператор yield return находится внутри одного или более блоков try, их соответствующие блоки finally не выполняются в это время;

o состояние объекта перечислителя меняется на suspended;

o метод MoveNext возвращает true вызвавшему его, указывая этим, что итерация успешно продвинулась к следующему значению.

· Если встретился оператор yield break (§8.14):

o если оператор yield break находится внутри одного или более блоков try, соответствующие им блоки finally выполняются;

o состояние объекта перечислителя меняется на after;

o метод MoveNext возвращает false вызвавшему его, указывая этим, что итерация выполнена.

· Если встретился конец блока итератора:

o состояние объекта перечислителя меняется на after;

o метод MoveNext возвращает false вызвавшему его, указывая этим, что итерация выполнена.

· Если инициируется исключение и распространяется из блока итератора:

o соответствующие блоки finally в теле итератора будут выполняться распространением исключения;

o состояние объекта перечислителя меняется на after;

o распространение исключения продолжается до вызвавшего метод MoveNext.