Подтвердить что ты не робот

В чем причина внедрения IEnumerable и IEnumerator

Я готовлюсь к своему С# EXAM. Я смущен ответом на этот вопрос:

Программа может использовать интерфейсы IEnumerable и IEnumerator для выполнения следующих действий:

а. Используйте MoveNext и Reset для перемещения по списку объектов.
б. Используйте foreach для перемещения по списку объектов.
с. Перемещение по списку объектов по индексу.
д. Используйте оператор yield return, чтобы составить список объектов для итерации.

Мой ответ был b). Но книга: MCSD Certification Toolkit говорит, что она a).

Может кто-нибудь сказать мне, почему? Я понимаю, что вы можете получить Enumerator с помощью GetEnumerator(), а затем вызвать методы MoveNext и Reset для перемещения по списку (и использовать Current для доступа к текущему элементу, на который ссылается итератор). Но не реализует ли IEnumerable и IEnumerator причину использования объекта в цикле foreach?

4b9b3361

Ответ 1

Правильный ответ a, и это понятно, если взглянуть на определения интерфейсов:

[GuidAttribute("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
[ComVisibleAttribute(true)]
public interface IEnumerable
{
    IEnumerator GetEnumerator();
}

И

[ComVisibleAttribute(true)]
[GuidAttribute("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerator
{
    Object Current { get; }
    bool MoveNext();
    void Reset();
}

Как вы заметили, когда тип реализует интерфейс IEnumerable, он должен иметь метод, который будет возвращать Enumerator, объект, реализующий интерфейс IEnumerator.

Тогда интерфейс под названием IEnumerator имеет одно свойство, которое содержит текущий объект, когда мы итерируем по коллекции и два метода, MoveNext и Reset. Под капотом, когда мы итерируем по коллекции, сначала вызывается метод Итератора MoveNext. Если это верно, мы получаем первый элемент - текущий объект. Затем метод, называемый MoveNext, вызывается снова и снова, пока он не вернет false. Каждый раз, когда MoveNext вызывается, мы получаем объект из коллекции, итерации.

Почему у нас есть метод Reset?

Как указано в MSDN:

Устанавливает перечислитель в исходное положение, которое перед первым элемент в коллекции.

Ответ 2

Когда вы реализуете интерфейс, вы соглашаетесь с контрактом: MoveNext и Reset. Другие варианты вопроса относятся к конкретным классам, реализующим интерфейс.

Ответ 3

Если MoveNext передает конец коллекции, перечислитель помещается после последнего элемента в коллекции, а MoveNext возвращает false. Когда перечислитель находится в этой позиции, последующие вызовы MoveNext также возвращают false. Если последний вызов MoveNext возвращает false, Current - undefined. Чтобы снова установить Current на первый элемент коллекции, вы можете вызвать Reset, а затем MoveNext.

нажмите здесь для подробного объяснения