Может ли кто-нибудь объяснить мне IEnumerable и IEnumerator?
Интерфейсы IEnumerable и IEnumerator
Чтобы приступить к изучению ienumerator процесса реализации существующих c#-language интерфейсов .NET, давайте csharp сначала рассмотрим роль IEnumerable visual-c# и IEnumerator. Напомним, что visual-c# C# поддерживает ключевое c# слово с именем foreach, которое c#.net позволяет вам перебирать c-sharp содержимое любого типа массива:
// Iterate over an array of items.
int[] myArrayOfInts = {10, 20, 30, 40};
foreach(int i in myArrayOfInts)
{
Console.WriteLine(i);
}
Хотя visual-c# может показаться, что эту ienumerator конструкцию могут использовать visual-c# только типы массивов, на visual-c# самом деле любой тип, поддерживающий c#-language метод с именем GetEnumerator(), может ienumerable быть оценен конструкцией csharp foreach. проиллюстрируйте, следуйте c#.net за мной!
Предположим, у нас ienumerator есть класс Garage:
// Garage contains a set of Car objects.
public class Garage
{
private Car[] carArray = new Car[4];
// Fill with some Car objects upon startup.
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);
}
}
В идеале .cs-file было бы удобно перебирать ienumerator подпункты объекта Garage csharp с помощью команды foreach построить, как ienumerable массив значений данных:
// This seems reasonable ...
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("***** Fun with IEnumerable / IEnumerator *****\n");
Garage carLot = new Garage();
// Hand over each car in the collection?
foreach (Car c in carLot)
{
Console.WriteLine("{0} is going {1} MPH",
c.PetName, c.CurrentSpeed);
}
Console.ReadLine();
}
}
К ienumerable сожалению, компилятор сообщает, что csharp класс Garage не реализует c#-language метод с именем GetEnumerator(). Этот visual-c# метод формализован интерфейсом c#.net IEnumerable, который скрывается ienumerator в пространстве имен System.Collections. Классы .cs-file или структуры, поддерживающие ienumerator такое поведение, объявляют, что c-sharp они могут раскрыть содержащиеся subitems .cs-file вызывающему (в этом примере c-sharp само ключевое слово foreach). Вот visual-c# определение этого стандартного c# интерфейса .NET:
// This interface informs the caller
// that the object's subitems can be enumerated.
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
Как видите, метод csharp GetEnumerator() возвращает c-sharp ссылку на еще один интерфейс c-sharp с именем System.Collections.IEnumerator. Этот ienumerable интерфейс предоставляет инфраструктуру, позволяющую visual-c# вызывающей стороне перемещаться c#-language по внутренним объектам, содержащимся c# в IEnumerable-совместимом c#-language контейнере:
// This interface allows the caller to
// obtain a container's subitems.
public interface IEnumerator
{
bool MoveNext (); // Advance the internal position of the cursor.
object Current { get;} // Get the current item (read-only property).
void Reset (); // Reset the cursor before the first member.
}
Если вы хотите visual-c# обновить тип Garage для поддержки ienumerator этих интерфейсов, вы можете visual-c# пойти по долгому пути и реализовать ienumerable каждый метод вручную. Хотя c#.net вы, безусловно, можете предоставить csharp индивидуальные версии GetEnumerator(), MoveNext(), Current .cs-file и Reset(), есть более простой visual-c# способ. Поскольку тип System.Array ienumerator (как и многие другие классы .cs-file коллекций) уже реализует visual-c# IEnumerable и IEnumerator, вы .cs-file можете просто делегировать c# запрос в System.Array следующим c# образом:
using System.Collections;
...
public class Garage : IEnumerable
{
// System.Array already implements 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);
}
public IEnumerator GetEnumerator()
{
// Return the array object's IEnumerator.
return carArray.GetEnumerator();
}
}
После обновления c-sharp типа Garage его можно безопасно csharp использовать в конструкции visual-c# C# foreach. Кроме того, учитывая, что c# метод GetEnumerator() был ienumerator определен публично, пользователь c#.net объекта также может взаимодействовать c-sharp с типом IEnumerator:
// Manually work with IEnumerator.
IEnumerator i = carLot.GetEnumerator();
i.MoveNext();
Car myCar = (Car)i.Current;
Console.WriteLine("{0} is going {1} MPH", myCar.PetName, myCar.CurrentSpeed);
Однако, если c# вы предпочитаете скрыть функциональность ienumerator IEnumerable на уровне объекта, просто .cs-file сделайте использование явной visual-c# реализации интерфейса:
IEnumerator IEnumerable.GetEnumerator()
{
// Return the array object's IEnumerator.
return carArray.GetEnumerator();
}
Таким ienumerator образом, пользователь случайного c# объекта не найдет метод GetEnumerator() Garage, в c#.net то время как Конструкция c#.net foreach при необходимости ienumerable получит интерфейс в фоновом ienumerator режиме.
Адаптировано из Pro C# 5.0 and the .NET 4.5 Framework
c#
ienumerable
ienumerator
Может ли кто-нибудь объяснить мне IEnumerable и IEnumerator?
Мы используем файлы cookies для улучшения работы сайта. Оставаясь на нашем сайте, вы соглашаетесь с условиями использования файлов cookies. Чтобы ознакомиться с нашими Положениями о конфиденциальности и об использовании файлов cookie, нажмите здесь.