yield (справочник по C#)
Если используется ключевое слово yield в инструкцию, означает, что метод, оператор или метод доступа get, в котором отображается итератор.Используется итератор, чтобы выполнять пользовательскую итерации по коллекции.В следующем примере показан 2 выписки формы yield.
yield return <expression>;
yield break;
Заметки
При использовании оператора yield return для возвращения каждый элемент по одному.
Используется метод итератора с помощью выписки foreach или запроса LINQ.Все итерации цикла foreach вызывает метод итератора.При достижении выписка yield return в методе итератора, возвращается значение expression и текущего расположения в коде сохраняются.Среда выполнения будет перезапуске из этого расположения при следующем вызове функции итератора данной функции.
Можно использовать выписка yield break для выполнения итерации.
Дополнительные сведения об итераторах см. в разделе Итераторы (C# и Visual Basic).
Методы итератора и получают доступ
Объявление итератора должно отвечать следующим требованиям.
Возвращаемый тип должен быть IEnumerable, IEnumerable<T>, IEnumerator или IEnumerator<T>.
Неявное преобразование из типа выражения должно существовать в инструкцию yield return к возвращаемому типу итератора.
Нельзя включить формулировку yield return или yield break в методах, которые имеют следующие характеристики:
Анонимные методы.Для получения дополнительной информации см. Анонимные методы (Руководство по программированию в C#).
Методы, содержащие опасные блоки.Для получения дополнительной информации см. unsafe (Справочник по C#).
Обработка исключений
Выписка yield return не удается найти в блок try-catch.Выписка yield return могут находиться в блоке try выписки try - окончательн.
Выписка yield break могут находиться в блоке try или catch, но не блок finally.
Если тело метода foreach (вне итератора) возникает исключение, то выполняется блок finally в методе итератора.
Техническая реализация
Следующий код возвращает значение IEnumerable<string> из метода итератора и затем перебираются элементы.
IEnumerable<string> elements = MyIteratorMethod();
foreach (string element in elements)
{
…
}
Вызов MyIteratorMethod не выполняет тело метода.Вместо этого вызов возвращается в переменную **IEnumerable<string>**elements.
В итерации цикла foreach, метод MoveNext вызывается для elements.Этот вызов выполняется тело MyIteratorMethod до тех пор, пока не будет достигнут следующую выписка yield return.Выражение, возвращаемое выпиской yield return определяется не только значение переменной element для использования циклом, но и свойства элементов Current, IEnumerable<string>.
В каждой последующей итерации цикла foreach, среда выполнения продолжает из тела итератора, где он вышло, снова остановка при достижении оператора yield return.Цикл foreach завершается при достижении конца итератора выписки или метода yield break.
Пример
В следующем примере два оператора yield return, внутри цикла for.Каждая итерация тела выписки foreach в Process создает вызов функции Power итератора.Каждый вызов функции итератора переходит к следующему выполнения выписки yield return, которая происходит во время следующей итерации цикла for.
Возвращаемый тип итератора метода IEnumerable, который является типом интерфейса итератора.Если метод вызывается итератора, он возвращает перечислимый объект, содержащий степени числа.
public class PowersOf2
{
static void Main()
{
// Display powers of 2 up to the exponent of 8:
foreach (int i in Power(2, 8))
{
Console.Write("{0} ", i);
}
}
public static System.Collections.IEnumerable Power(int number, int exponent)
{
int result = 1;
for (int i = 0; i < exponent; i++)
{
result = result * number;
yield return result;
}
}
// Output: 2 4 8 16 32 64 128 256
}
В следующем примере демонстрируется доступа get, итератор.В этом примере, каждая выписка yield return возвращает экземпляр определяемого пользователем класса.
public static class GalaxyClass
{
public static void ShowGalaxies()
{
var theGalaxies = new Galaxies();
foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy)
{
Debug.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString());
}
}
public class Galaxies
{
public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy
{
get
{
yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 };
yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 };
yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 };
yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 };
}
}
}
public class Galaxy
{
public String Name { get; set; }
public int MegaLightYears { get; set; }
}
}
Спецификация языка C#
Дополнительные сведения см в Спецификация языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.
См. также
Ссылки
foreach, in (Справочник по C#)
Основные понятия
Руководство по программированию на C#