Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp Language Specification.doc
Скачиваний:
13
Добавлен:
26.09.2019
Размер:
4.75 Mб
Скачать

8.14Оператор yield

Оператор yield используется в блоке итератора (§8.2) для выдачи значения в объект перечислителя (§10.14.4) или в перечислимый объект итератора (§10.14.5), либо для сигнализации об окончании итерации.

оператор_yield: yield return выражение ; yield break ;

yield не является зарезервированным словом; оно приобретает особый смысл только тогда, когда стоит непосредственно перед ключевым словом return или break. В других контекстах yield может использоваться как идентификатор.

На использование оператора yield накладывается ряд ограничений.

  • Использование оператора yield (в любой из двух форм) вне тела_метода, тела_оператора или тела_метода_доступа вызывает ошибку времени компиляции.

  • Использование оператора yield (в любой из двух форм) внутри анонимной функции вызывает ошибку времени компиляции.

  • Использование оператора yield (в любой из двух форм) в предложении finally оператора try вызывает ошибку времени компиляции.

  • Использование оператора yield return в любом месте оператора try, содержащего предложения catch, вызывает ошибку времени компиляции.

В следующем примере демонстрируется несколько допустимых и недопустимых способов использования оператора yield.

delegate IEnumerable<int> D();

IEnumerator<int> GetEnumerator() { try { yield return 1; // Ok yield break; // Ok } finally { yield return 2; // Error, yield in finally yield break; // Error, yield in finally }

try { yield return 3; // Error, yield return in try...catch yield break; // Ok } catch { yield return 4; // Error, yield return in try...catch yield break; // Ok }

D d = delegate { yield return 5; // Error, yield in an anonymous function }; }

int MyMethod() { yield return 1; // Error, wrong return type for an iterator block }

Должно существовать неявное преобразование (§6.1) типа выражения оператора yield return в тип выдачи итератора (§10.14.3).

Оператор yield return выполняется следующим образом.

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

  • Выполнение блока итератора приостанавливается. Если оператор yield return находится внутри одного или более блоков try, их соответствующие блоки finally не выполняются в это время;

  • Метод MoveNext объекта перечислителя возвращает true в вызвавшую его программу, тем самым указывая на успешный переход объекта перечислителя к следующему элементу.

Следующий вызов метода MoveNext объекта перечислителя возобновляет выполнение блока итератора с того места, где оно было приостановлено.

Оператор yield break выполняется следующим образом.

  • Если оператор yield break входит в один или несколько блоков try, с которыми связаны соответствующие блоки finally, управление вначале передается в блок finally самого внутреннего оператора try. Если управление достигает конечной точки блока finally, после этого управление передается в блок finally следующего объемлющего оператора try. Этот процесс повторяется до тех пор, пока не будут выполнены все блоки finally всех объемлющих операторов try.

  • Управление возвращается в метод, вызвавший блок итератора. Это либо метод MoveNext, либо метод Dispose объекта перечислителя.

Поскольку оператор yield осуществляет безусловную передачу управления в другое место, конечная точка оператора yield никогда не будет достижима.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]