public class Garage : IEnumerable
{
// System.Array уже реализует IEnumerator!
private Car[] carArray = new Car[4];
public Garage
{
carArray[0] = new Car("FeeFee", 200);
carArray[1] = new Car("Clunker", 90);
carArray[2] = new Car("Zippy", 30);
carArray[3] = new Car("Fred", 30);
}
// Возвратить IEnumerator объекта массива.
public IEnumerator GetEnumerator
=> carArray.GetEnumerator;
}
После такого изменения тип Garage
foreach. Более того, учитывая, что метод GetEnumerator был определен как открытый, пользователь объекта может также взаимодействовать с типом IEnumerator:// Вручную работать с IEnumerator.
IEnumerator carEnumerator = carLot.GetEnumerator;
carEnumerator.MoveNext;
Car myCar = (Car)i.Current;
Console.WriteLine("{0} is going {1} MPH", myCar.PetName, myCar.CurrentSpeed);
Тем не менее, если вы предпочитаете скрыть функциональность IEnumerable
// Возвратить IEnumerator объекта массива.
IEnumerator IEnumerable.GetEnumerator
=> return carArray.GetEnumerator;
В результате обычный пользователь объекта не обнаружит метод GetEnumerator
Garage, в то время как конструкция foreach при необходимости будет получать интерфейс в фоновом режиме.Построение итераторных методов с использованием ключевого слова yield
Существует альтернативный способ построения типов, которые работают с циклом foreach
foreach. В целях иллюстрации создайте новый проект консольного приложения по имени CustomEnumeratorWithYield и вставьте в него типы Car, Radio и Garage из предыдущего примера (снова переименовав пространство имен согласно текущему проекту). Затем модифицируйте тип Garage:public class Garage : IEnumerable
{
...
// Итераторный метод.
public IEnumerator GetEnumerator
{
foreach (Car c in carArray)
{
yield return c;
}
}
}
Обратите внимание, что показанная реализация метода GetEnumerator
foreach и возвращает каждый объект Car вызывающему коду, используя синтаксис yield return. Ключевое слово yield применяется для указания значения или значений, которые подлежат возвращению конструкцией foreach вызывающему коду. При достижении оператора yield return текущее местоположение в контейнере сохраняется и выполнение возобновляется с этого местоположения, когда итератор вызывается в следующий раз.Итераторные методы не обязаны использовать ключевое слово foreach
public IEnumerator GetEnumerator
{
yield return carArray[0];
yield return carArray[1];
yield return carArray[2];
yield return carArray[3];
}
В этой реализации обратите внимание на то, что при каждом своем прохождении метод GetEnumerator
carArray, то метод GetEnumerator станет рассогласованным. Тем не менее, такой синтаксис может быть полезен, когда вы хотите возвращать из метода локальные данные для обработки посредством foreach.Защитные конструкции с использованием локальных функций (нововведение в версии 7.0)
Бьёрн Страуструп , Ирина Сергеевна Козлова , Бьерн Страуструп , Валерий Федорович Альмухаметов
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT