Есть ли разница между методами итератора, возвращающими IEnumerable <T>и IEnumerator <T>? - PullRequest
7 голосов
/ 06 января 2009

Рассмотрим два метода итераторов с одинаковыми телами:

public static IEnumerable<int> It1() { 
    ...
}

public static IEnumerator<int> It2() { 
    ...
}

Существуют ли обстоятельства, при которых звонок It2 отличается от звонка It1.GetEnumerator()?

Есть ли когда-нибудь веская причина для определения итератора как IEnumerator<T> сверх IEnumerable<T>? Единственное, о чем я могу думать, это когда вы реализуете IEnumerable<T>.GetEnumerator().

РЕДАКТИРОВАТЬ: Под методами итератора я имею в виду методы, использующие конструкции yield return и yield break.

Ответы [ 2 ]

8 голосов
/ 06 января 2009

Как уже отмечалось, вы не можете foreach более IEnumerator<T>. Из-за этого затрудняется интеграция в те места кода, где вы хотите перебрать то, что возвращаете.

Кроме того, здесь важно, что IEnumerable<T> предназначен для фабрики, так что вы можете создавать реализации IEnumerator<T>, которые не связаны напрямую с реализацией коллекции T.

Еще более важным сейчас является тот факт, что все методы расширения для LINQ работают IEnumerable<T>, поэтому вы захотите упростить работу со своими перечислениями, возвращая это.

1 голос
/ 14 декабря 2011

Вы бы сделали это, если хотите взять на себя ответственность за написание IEnumerable<T> класса-оболочки.

Допустим, у вас есть класс, для которого вы хотите выполнять перечисление бесконечно:

public class EveryDateInTheFuture : IEnumerable<DateTime>
{
    public EveryDateInTheFuture() { this.StartDate = DateTime.Today; }

    public DateTime StartDate { get; set; }

    public IEnumerator<DateTime> GetEnumerator()
    {
         while (true)
         {
             yield return date;
             date = date.AddDays(1);
         }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...