Зачем нам нужны 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 интерфейс), который вы можете рассматривать как "указатель" на текущую позицию в вашем итерируемом объекте. Поскольку у вас могут быть внутренние циклы (то есть несколько итераций для одного и того же объекта за один раз), вы должны отделить итерируемый объект от итератора.

По сути, существует множество способов обхода определенной последовательности, но шаблон итератора дает вам возможность "обобщить" этот подход, скрывая конкретную реализацию алгоритма обхода от вызывающих внутри реализации.

Другие вопросы по тегам