Хотя может показаться, что данная конструкция подходит только для массивов, на самом деле foreach
GetEnumerator. В целях иллюстрации создайте новый проект консольного приложения по имени CustomEnumerator. Скопируйте в новый проект файлы Car.cs и Radio.cs из проекта SimpleException, рассмотренного в главе 7. Не забудьте поменять пространства имен для классов на CustomEnumerator.Теперь вставьте в проект новый класс Garage
Car (автомобиль) внутри System.Array:using System.Collections;
namespace CustomEnumerator
{
// Garage содержит набор объектов Car.
public class Garage
{
private Car[] carArray = new Car[4];
// При запуске заполнить несколькими объектами Car.
public Garage
{
carArray[0] = new Car("Rusty", 30);
carArray[1] = new Car("Clunker", 55);
carArray[2] = new Car("Zippy", 30);
carArray[3] = new Car("Fred", 30);
}
}
}
В идеальном случае было бы удобно проходить по внутренним элементам объекта Garage
foreach как в ситуации с массивом значений данных:using System;
using CustomEnumerator;
// Код выглядит корректным...
Console.WriteLine("***** Fun with IEnumerable / IEnumerator *****\n");
Garage carLot = new Garage;
// Проход по всем объектам Car в коллекции?
foreach (Car c in carLot)
{
Console.WriteLine("{0} is going {1} MPH",
c.PetName, c.CurrentSpeed);
}
Console.ReadLine;
К сожалению, компилятор информирует о том, что в классе Garage не реализован метод по имени GetEnumerator
IEnumerable, находящемся в пространстве имен System.Collections.На заметку!
В главе 10 вы узнаете о роли обобщений и о пространстве именSystem.Collections.Generic. Как будет показано, это пространство имен содержит обобщенные версии интерфейсов IEnumerable/IEnumerator, которые предлагают более безопасный к типам способ итерации по элементам.Классы или структуры, которые поддерживают такое поведение, позиционируются как способные предоставлять вызывающему коду доступ к элементам, содержащимся внутри них (в рассматриваемом примере самому ключевому слову foreach
// Данный интерфейс информирует вызывающий код о том,
// что элементы объекта могут перечисляться
public interface IEnumerable
{
IEnumerator GetEnumerator;
}
Как видите, метод GetEnumerator
System.Collections.IEnumerator, обеспечивающий инфраструктуру, которая позволяет вызывающему коду обходить внутренние объекты, содержащиеся в совместимом с IEnumerable контейнере:// Этот интерфейс позволяет вызывающему коду получать элементы контейнера.
public interface IEnumerator
{
bool MoveNext ; // Переместить вперед внутреннюю позицию курсора.
object Current { get;} // Получить текущий элемент
// (свойство только для чтения).
void Reset ; // Сбросить курсор в позицию перед первым элементом.
}
Если вы хотите обновить тип Garage
GetEnumerator, MoveNext, Current и Reset, существует более легкий путь. Поскольку тип System.Array (а также многие другие классы коллекций) уже реализует интерфейсы IEnumerable и IEnumerator, вы можете просто делегировать запрос к System.Array следующим образом (обратите внимание, что в файл кода понадобится импортировать пространство имен System.Collections):using System.Collections;
...
Бьёрн Страуструп , Ирина Сергеевна Козлова , Бьерн Страуструп , Валерий Федорович Альмухаметов
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT