onlinechitalka.com/
onlinechitalka.com » Компьютеры и Интернет » Базы данных » Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю

Полная версия книги - "Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю"

На этом ресурсе Вы можете бесплатно читать книгу онлайн Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю. Жанр: Базы данных . На сайте onlinechitalka.com Вы можете онлайн читать полную версию книги без регистрации и sms. Так же Вы можете ознакомится с содержанием, описанием, предисловием о произведении
Перейти на страницу:

Вспомните средство локальных функций версии C# 7, представленное в главе 4; локальные функции — это закрытые функции, которые определены внутри других функций. За счет перемещения

yield return
внутрь локальной функции, которая возвращается из главного тела метода, операторы верхнего уровня (до возвращения локальной функции) выполняются немедленно. Локальная функция выполняется при вызове
MoveNext()
.

Приведите метод к следующему виду:

public IEnumerator GetEnumerator()

{

  // Это исключение сгенерируется немедленно

  throw new Exception("This will get called");

  return ActualImplementation();

  // Локальная функция и фактическая реализация IEnumerator

  IEnumerator ActualImplementation()

  {

    foreach (Car c in carArray)

    {

      yield return c;

    }

  }

}

Ниже показан тестовый код:

Console.WriteLine("***** Fun with the Yield Keyword *****n");

Garage carLot = new Garage();

try

{

  // На этот раз возникает ошибка

  var carEnumerator = carLot.GetEnumerator();

}

catch (Exception e)

{

  Console.WriteLine($"Exception occurred on GetEnumerator");

}

Console.ReadLine();

В результате такого обновления метода

GetEnumerator()
исключение генерируется незамедлительно, а не при вызове
MoveNext()
.

Построение именованного итератора

Также интересно отметить, что ключевое слово

yield
формально может применяться внутри любого метода независимо от его имени. Такие методы (которые официально называются именованными итераторами) уникальны тем, что способны принимать любое количество аргументов. При построении именованного итератора имейте в виду, что метод будет возвращать интерфейс
IEnumerable
, а не ожидаемый совместимый с
IEnumerator
тип. В целях иллюстрации добавьте к типу
Garage
следующий метод (использующий локальную функцию для инкапсуляции функциональности итерации):

public IEnumerable GetTheCars(bool returnReversed)

{

  // Выполнить проверку на предмет ошибок

  return ActualImplementation();

  IEnumerable ActualImplementation()

  {

    // Возвратить элементы в обратном порядке.

    if (returnReversed)

    {

      for (int i = carArray.Length; i != 0; i--)

      {

        yield return carArray[i - 1];

      }

    }

    else

    {

      // Возвратить элементы в том порядке, в каком они размещены в массиве.

      foreach (Car c in carArray)

      {

        yield return c;

      }

    }

  }

}

Обратите внимание, что новый метод позволяет вызывающему коду получать элементы в прямом, а также в обратном порядке, если во входном параметре указано значение

true
. Теперь взаимодействовать с методом
GetTheCars()
можно так (обязательно закомментируйте оператор
throw new
в методе
GetEnumerator()
):

Console.WriteLine("***** Fun with the Yield Keyword *****n");

Garage carLot = new Garage();

// Получить элементы, используя GetEnumerator().

foreach (Car c in carLot)

{

  Console.WriteLine("{0} is going {1} MPH",

    c.PetName, c.CurrentSpeed);

}

Console.WriteLine();

<b>// Получить элементы (в обратном порядке!)</b>

<b>// с применением именованного итератора.</b>

foreach (Car c in carLot.GetTheCars(true))

{

  Console.WriteLine(&quot;{0} is going {1} MPH&quot;,

    c.PetName, c.CurrentSpeed);

}

Console.ReadLine();

Наверняка вы согласитесь с тем, что именованные итераторы являются удобными конструкциями, поскольку они позволяют определять в единственном специальном контейнере множество способов запрашивания возвращаемого набора.

Итак, в завершение темы построения перечислимых объектов запомните: для того, чтобы специальные типы могли работать с ключевым словом

foreach
языка С#, контейнер должен определять метод по имени
GetEnumerator()
, который формально определен интерфейсным типом
IEnumerable
. Этот метод обычно реализуется просто за счет делегирования работы внутреннему члену, который хранит подобъекты, но допускается также использовать синтаксис
yield return
, чтобы предоставить множество методов "именованных итераторов". 

Перейти на страницу:

Отзывы читателей о книге Язык программирования C#9 и платформа .NET5, автор: Троелсен Эндрю. Читайте комментарии и мнения людей о произведении.


Прокомментировать
Подтвердите что вы не робот:*
Все материалы на сайте размещаются его пользователями.
Администратор сайта не несёт ответственности за действия пользователей сайта..
Вы можете направить вашу жалобу на почту bookreadinfo@gmail.com
© 2020 - 2026 onlinechitalka.com