Не пойму я этот 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);