Создание пользовательского нумератора(интерфейсы lEnumerable и lEnumerator)
Для этого примера нам потребуется класс Cars, который представляет собойнабор уже знакомых нам объектов класса Саr Вот исходноеопределение класса Cars:// Cars - набор объектов класса Саrpublic class Cars{private Car[] carArray;// При создании объекта класса Cars заполняем его несколькими объектами Сагpublic Cars(){carArray = new Car[4];carArray[0] - new Car(“FeeFee”, 200, 0);carArray[l] = new Car(“Clunker“, 90. 0);carArray[2] - new Car(“Zippy”, 30. 0);carArray[l] - new Car(“Fred”, 30, 0);}}
// Кажется очень заманчивымpublic class CarDriverpublic static void Main(){Cars carLot = new Cars();// Пробуем использовать foreach для обращения к каждому объекту Саг внутри// набора, представленного carLotforeach(Car с in carlot){{Console.WriteLinet("Name: {0}“, c.PetName);Console.WrlteLlne("Max speed: {0}“, c.MaxSpeed);}}}
// Для применения конструкции foreach необходимо, чтобы класс реализовывал интерфейсI Enumerablepublic class Cars : lEnumerable{// Интерфейс lEnumerable определяет этот метод (и ничего больше):public IEnumerator GetEnumerator(){// А дальше-то что?}
// GetEnumerator() возвращает что-нибудь из нижеперечисленногоpublic interface lEnumeratorbool MoveNext(); // Передвинуть внутренний указатель (курсор)// на одну позициюobject Current {get:} // Получить текущий элемент набора (свойство только// для чтения)void Reset(); // Установить курсор в начало набора (на первый// обьект)}Учитывая, что lEnumerable.GetEnumerator() возвращает интерфейс lEnumerator,класс Cars придется переделать следующим образом:// Уже теплееpublic class Cars: lEnumerable. lEnumerator{// Реализация lEnumerablepublic lEnumerator GetEnumerator(){return (lEnumerator)this;}
// Набор объектов Саг с реализованный нумератором!public class Cars: Enumerator, Enumerable{
private car[] carArray:// Переменная для текущей позиции элемента в массиве
int pos = -1;public Cars (){
// Здесь иы создаем несколько объектов класса Саг и добавляем их в массив }// Реализация методов интерфейса IEnumeratorpublic bool MoveNext(){
if (pos < carArray.Length>{pos++;return true:}elsereturn false: }
public void Reset () { pos = 0: }public object Current{get { return carArray[pos] ; }// Реализация метода интерфейса lEnumerablepublic Enumerator GetEnumerator[]{return (lEnumerator)this:} }
Во-первых, теперь с нашим классом стало возможно работать при помощи синтаксисаforeach:// Ура!foreach <Car с in carLot>{
Console.WriteLine("Name: {0}", c.PetName);Console.WriteLine("Max speed: {0}“, c.MaxSpeed):
}Во-вторых, теперь в нашем распоряжении есть новые способы обращения к объектам класса Саг, находящимся внутри объекта класса Cars (что очень похоже на интерфейс lEnumXXXX в СОМ):// Обращаемся к объектам Саг через IEnumerator
lEnumerator itfEnum;itfEnum = (lEnumerator)carLot;
// Устанавливаем курсор на началоitfEnum.Reset();
// Перемещаем курсор вперед на один шагItfEnum.MoveNext();
// Выбираем одну машину и включаем в ней радиоobject curCar = itfEnum.Current;((Саг)сurСаг).CrankTunes(true):