В чем разница между IEnumerator и IEnumerable?

Возможный дубликат:
Кто-нибудь может объяснить Мне IEnumerable и IEnumerator?

В чем разница между IEnumerator и IEnumerable?


person Community    schedule 06.03.2009    source источник
comment
Дубликат: http://stackoverflow.com/questions/558304/can-anyone-explain-ienumerable-and-ienumerator-to-me   -  person Andrew Hare    schedule 06.03.2009
comment
Эта статья может вам помочь. c-sharpcorner.com/UploadFile/219d4d /   -  person Bimal Das    schedule 29.06.2018


Ответы (4)


IEnumerable - это интерфейс, который определяет один метод GetEnumerator, который возвращает IEnumerator, это, в свою очередь, обеспечивает доступ к коллекции только для чтения. Коллекцию, реализующую IEnumerable, можно использовать с оператором foreach.

Определение

IEnumerable 

public IEnumerator GetEnumerator();

IEnumerator

public object Current;
public void Reset();
public bool MoveNext();

пример кода с codebetter.com

person cgreeno    schedule 06.03.2009
comment
@Rex M: Я думаю, что код имеет смысл. IEnumerable имеет метод GetEnumerator, который возвращает IEnumer ator, а не IEnumer able. - person Lernkurve; 17.06.2010
comment
@Lernkurve, ответ был изменен и стал правильным после того, как я опубликовал свой комментарий. - person Rex M; 17.06.2010
comment
Эта статья может вам помочь. c-sharpcorner.com/UploadFile/219d4d / - person Bimal Das; 29.06.2018
comment
Я хотел бы добавить, что реализация IEnumerable не является абсолютным требованием для использования класса с оператором foreach. Требуется только подходящий IEnumerator<T> GetEnumerator() метод. - person rexcfnghk; 17.09.2018
comment
Фактические требования для цикла foreach еще менее строгие и вообще не привязаны к этим интерфейсам. Компилятор выполняет сопоставление с образцом. Метод GetEnumerator просто должен вернуть класс / структуру, которая, в свою очередь, имеет свойство Current и метод MoveNext, который возвращает bool. Я настоятельно рекомендую сообщение в блоге Эрика Липперса о сопоставлении с образцом. - person Bunny83; 30.07.2019

IEnumerator - это то, что можно перечислить: у него есть свойство Current и методы MoveNext и Reset (которые в коде .NET вы, вероятно, не будете вызывать явно, хотя могли).

IEnumerable - это вещь, которую можно перечислить ... что просто означает, что у нее есть метод GetEnumerator, который возвращает IEnumerator.

Что вы используете? Единственная причина использовать IEnumerator - это если у вас есть что-то, что имеет нестандартный способ перечисления (то есть, возвращая свои различные элементы один за другим), и вам нужно определить, как это работает. Вы бы создали новый класс, реализующий IEnumerator. Но вам все равно нужно вернуть этот IEnumerator в классе IEnumerable.

Чтобы узнать, как выглядит перечислитель (реализующий IEnumerator<T>), см. Любой класс Enumerator<T>, например, содержащиеся в List<T>, Queue<T>, или Stack<T>. Чтобы узнать о классе, реализующем IEnumerable, см. Любой стандартный класс коллекции.

person Ryan Lundy    schedule 06.03.2009
comment
Тогда зачем нам эта абстракция IEnumerable, если единственное, что она делает, это просто предоставляет доступ к Enumerator? Почему бы вместо этого просто не использовать Enumerator - person madmanul; 12.04.2018
comment
@xalz, они делают две разные вещи. IEnumerable отвечает на вопрос: Могу ли я перечислить свои элементы? IEnumerator отвечает на вопрос: Как мне перечислить мои элементы? Если у вас есть десять разных коллекций, которые перечисляются одинаково, вам не нужно определять, как каждая из них перечисляется отдельно. Итак, у вас есть общий класс реализации IEnumerator для всех десяти, и каждая коллекция просто должна реализовать IEnumerable, используя этот класс перечисления. Речь идет о разделении ответственности, рассматривая хранение данных и перечисление данных как отдельные операции. - person Ryan Lundy; 12.04.2018

Знак Enumerator показывает вам элементы в списке или коллекции. Каждый экземпляр Enumerator находится в определенной позиции (1-й элемент, 7-й элемент и т. Д.) И может предоставить вам этот элемент (IEnumerator.Current) или перейти к следующему (IEnumerator.MoveNext). Когда вы пишете цикл foreach на C #, компилятор генерирует код, использующий перечислитель.

Enumerable - это класс, который может дать вам Enumerator. У него есть метод GetEnumerator, который дает вам Enumerator, который просматривает его элементы. Когда вы пишете цикл foreach на C #, генерируемый им код вызывает GetEnumerator для создания Enumerator, используемого циклом.

person SLaks    schedule 06.03.2009
comment
Это сообщение в блоге довольно неточно. - person SLaks; 22.01.2012

IEnumerable и IEnumerator - оба интерфейса. IEnumerable имеет только один метод, называемый GetEnumerator. Этот метод возвращает (поскольку все методы возвращают что-то, включая void) другой тип, который является интерфейсом, и этим интерфейсом является IEnumerator. Когда вы реализуете логику перечислителя в любом классе вашей коллекции, вы реализуете IEnumerable (общий или не общий). IEnumerable имеет только один метод, тогда как IEnumerator имеет 2 метода (MoveNext и Reset) и свойство Current. Для облегчения понимания рассмотрите IEnumerable как коробку, которая содержит IEnumerator внутри (но не через наследование или включение). См. Код для лучшего понимания:

class Test : IEnumerable, IEnumerator
{
    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }

    public object Current
    {
        get { throw new NotImplementedException(); }
    }

    public bool MoveNext()
    {
        throw new NotImplementedException();
    }

    public void Reset()
    {
        throw new NotImplementedException();
    }
}
person James Kingsbery    schedule 06.03.2009