Возможный дубликат:
Кто-нибудь может объяснить Мне IEnumerable и IEnumerator?
В чем разница между IEnumerator и IEnumerable?
Возможный дубликат:
Кто-нибудь может объяснить Мне IEnumerable и IEnumerator?
В чем разница между IEnumerator и IEnumerable?
IEnumerable - это интерфейс, который определяет один метод GetEnumerator, который возвращает IEnumerator, это, в свою очередь, обеспечивает доступ к коллекции только для чтения. Коллекцию, реализующую IEnumerable, можно использовать с оператором foreach.
Определение
IEnumerable
public IEnumerator GetEnumerator();
IEnumerator
public object Current;
public void Reset();
public bool MoveNext();
IEnumerable
не является абсолютным требованием для использования класса с оператором foreach
. Требуется только подходящий IEnumerator<T> GetEnumerator()
метод.
- person rexcfnghk; 17.09.2018
IEnumerator
- это то, что можно перечислить: у него есть свойство Current
и методы MoveNext
и Reset
(которые в коде .NET вы, вероятно, не будете вызывать явно, хотя могли).
IEnumerable
- это вещь, которую можно перечислить ... что просто означает, что у нее есть метод GetEnumerator, который возвращает IEnumerator
.
Что вы используете? Единственная причина использовать IEnumerator
- это если у вас есть что-то, что имеет нестандартный способ перечисления (то есть, возвращая свои различные элементы один за другим), и вам нужно определить, как это работает. Вы бы создали новый класс, реализующий IEnumerator
. Но вам все равно нужно вернуть этот IEnumerator
в классе IEnumerable
.
Чтобы узнать, как выглядит перечислитель (реализующий IEnumerator<T>
), см. Любой класс Enumerator<T>
, например, содержащиеся в List<T>
, Queue<T>,
или Stack<T>
. Чтобы узнать о классе, реализующем IEnumerable
, см. Любой стандартный класс коллекции.
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
, используемого циклом.
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();
}
}