Не пойму я этот Yield - C#
Формулировка задачи:
Здравствуйте. Всё никак не могу вникнуть в его суть! Хотя в случаях, когда IEnumerable и IEnumerator реализуются без него, я всё понимаю
Итак, вот примеры кода:
"...Метод GetEnumerator() теперь и будет являться итератором..."
Ок. Получается, что мы используем yield, чтобы не писать вручную методы интерфейса IEnumerator. Правильно?
Вот вызываем в главной программе:
А теперь
"..Но оператор yield можно использовать внутри любого метода, только такой метод должен возвращать объект интерфейса IEnumerable. Подобные методы еще называют именованными итераторами."
MAIN:
В первом варианте еще ладно: мы называем метод итератором, он возвращает значение типа IEnumerator.
Но тут мой мозг вспыхнул. Почему во втором примере метод, который возвращает IEnumerable - итератор?
Почему в первом случае мы в foreach обращаемся к самой коллекции, а во втором - вызываем на ней метод?
Насколько я понимаю, в общем случае foreach, чтобы приступить к работе с коллекцией, делает именно два шага: сначала приводит её к IEnumerable, а затем к IEnumerator. Пользуясь методами этого интерфейса, т.е. непосредственно ИТЕРАТОРОМ, он уже и перебирает коллекцию.
Но я никак не могу связать примеры выше с этой теорией
Прошу не отсылать меня на msdn, просто там эта тема объясняется поверхностно
Листинг программы
- IEnumerator IEnumerable.GetEnumerator()
- {
- for (int i = 0; i < books.Length; i++)
- {
- yield return books[i];
- }
- }
Листинг программы
- foreach (Book b in library)
- {
- Console.WriteLine(b.Name);
- }
Листинг программы
- public IEnumerable GetBooks(int max)
- {
- for (int i = 0; i < max; i++)
- {
- if (i == books.Length)
- {
- yield break;
- }
- else
- {
- yield return books[i];
- }
- }
- }
Листинг программы
- Library library = new Library();
- foreach (Book b in library.GetBooks(5))
- {
- Console.WriteLine(b.Name);
- }
Правильно я понимаю, что вызывая на коллекции метод, возвращающий IEnumerable, foreach, согласно моим предположениям выше, делает первый шаг, а потом благодаря
yield
перебирает коллекцию так, как если бы она реализовывала методы MoveNext, Reset и Current?Решение задачи: «Не пойму я этот Yield»
textual
Листинг программы
- foreach (string element in UserCollection) //будет ошибка. А если добавить .Power(), как выше, то не будет
- Console.WriteLine(element);
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д