Зачем нам нужны IEnumerator и IEnumerable?
Итак, я просто работал через IEnumerator
а также IEnumerable
, Теперь в MSDN говорится, что главная цель этих вещей состоит в том, чтобы перебрать коллекцию клиентов.
Вполне справедливо, однако, что я мог перебирать пользовательскую коллекцию без использования того или другого (или, по крайней мере, мне бы хотелось так думать)
namespace ienumerator
{
class person
{
public person(string first, string second)
{
fname = first;
lname = second;
}
public string fname { get; set; }
public string lname { get; set; }
}
class person_list
{
public person[] list;
public person_list(person[] per)
{
list = new person[per.Length];
for (int i = 0; i < per.Length; i++)
{
list[i] = per[i];
}
}
}
class Program
{
static void Main(string[] args)
{
person[] names = new person[3]
{
new person("some","one"),
new person("another","one"),
new person("sss","ssdad"),
};
person_list list_of_names = new person_list(names);
int i = 0;
while (i < list_of_names.list.Length)
{
Console.WriteLine(list_of_names.list[i].fname);
i++;
}
Console.Read();
}
}
}
Так что в моем понимании есть недостатки: вышесказанное дает мне тот же результат, которого я достиг после реализации IEnumerator
а также IEnumerable
,
5 ответов
Однако я был в состоянии перебрать пользовательскую коллекцию без использования
Конечно, вы можете перебирать свою собственную коллекцию без интерфейса; если бы вы не могли, то как бы вы реализовали интерфейс?
Вы, как разработчик кода, не реализуете интерфейс для вашего удобства. Вы реализуете это для удобства потребителя вашего кода. Интерфейс означает "внимание клиента: вы можете перечислить содержимое этой коллекции, не зная, как я ее реализовал".
Это цель интерфейса: он предоставляет абстракцию, которая позволяет потребителям вашего кода использовать его, не разбираясь в том, как он работает.
В вашем main
Функция, которую вы использовали два аспекта person_list
перебирать список людей, Length
и []
оператор для принятия члена коллекции на определенную позицию.
Тем не менее, что, если у вас есть какой-то контейнер или пользовательская коллекция, в которой не реализован ни один, ни оба из них? Например, класс, который читает файл построчно, может не знать заранее, какова была длина коллекции, и поэтому не может определить Length
, Перечислитель, который читает сообщения из очереди, может занять только следующее, а не одну, скажем, на четыре позиции впереди. [4]
, В обоих случаях вы все равно можете "перебрать" коллекцию должным образом.
IEnumerator
а также IEnumerable
требуют именно те атрибуты, которые необходимы для foreach
работать, а не других, поэтому функции могут использовать их в качестве требований, зная, что они смогут перебирать любой тип коллекции, которую они передают.
На самом деле, в C# не требуется реализовывать IEnumerable
а также IEnumerator
настроить свои собственные коллекции. Если вы перебираете коллекцию, используя традиционный способ, который вам подходит, но это будет проблемой, если вы используете foreach
итерировать коллекцию.
Другая причина, если вы хотите представить свой класс так, чтобы пользователь VB.NET мог использовать его, вам следует рассмотреть возможность реализации обоих интерфейсов.
Обратите внимание, что IEnumerable
разница в неуниверсальных и родовых коллекциях Неуниверсальный принадлежит System.Collection
другой принадлежит System.Collection.Generic
Пространство имен
Конечно, вы можете перебирать пользовательскую коллекцию без реализации IEnumerable
интерфейс, но затем итерационный код должен знать вашу пользовательскую коллекцию.
Если вы реализуете IEnumerable
код, который перебирает все элементы, не обязательно должен знать ваш person_list
учебный класс. Он использует экземпляр некоторого класса, который реализует IEnumerable
и он все равно будет работать, если вы обменяете фактический экземпляр на что-то еще, что также реализует IEnumerable
позже.
Существует множество способов перебора пользовательских последовательностей. Один из способов сделать это - использовать Pattern Design Iterator.
Шаблон Iterator используется для унификации обхода пользовательской последовательности (это может быть коллекция в памяти, сгенерированная коллекция или что-то еще). В мире.NET этот шаблон реализован следующим образом: у нас есть итеративный объект, который реализует IEnumerable
интерфейс (и это показывает любому клиенту вашего класса, что у вас есть возможность обходить свой контент).
И у нас есть сам итератор (объект, который реализует IEnumerator
интерфейс), который вы можете рассматривать как "указатель" на текущую позицию в вашем итерируемом объекте. Поскольку у вас могут быть внутренние циклы (то есть несколько итераций для одного и того же объекта за один раз), вы должны отделить итерируемый объект от итератора.
По сути, существует множество способов обхода определенной последовательности, но шаблон итератора дает вам возможность "обобщить" этот подход, скрывая конкретную реализацию алгоритма обхода от вызывающих внутри реализации.