IEnumerable <T>предоставляет два метода GetEnumerator - в чем разница между ними? - PullRequest
8 голосов
/ 18 февраля 2009

Когда я использую интерфейс IEnumerable<T>, я вижу два GetEnumerator метода: один возвращает IEnumerator, а другой IEnumerator<T>. Когда я буду использовать один или другой?

Ответы [ 5 ]

33 голосов
/ 18 февраля 2009

Вы обычно реализуете оба. Одним из них является более новая, универсальная версия, которая возвращает типизированный перечислитель (IEnumerator<T>). Другой - для совместимости с устаревшим кодом (возвращает IEnumerator). Типичная реализация:

public IEnumerator<T> GetEnumerator() {
    foreach(T item in items) {
        yield return item;
    }
}

IEnumerator IEnumerable.GetEnumerator() {
    return GetEnumerator();
}
12 голосов
/ 18 февраля 2009

Причина в том, что есть два метода, в том, что IEnumerable<T> наследует интерфейс IEnumerable, поэтому вы видите универсальный метод из IEnumerable<T> и неуниверсальный метод из IEnumerable.

Вот как вы хотите реализовать интерфейс в вашем типе:

class Foo : IEnumerable<Foo>
{
    public IEnumerator<Foo> GetEnumerator()   
    {
        // do your thing here
    }

    // do a EIMI here and simply call the generic method
    IEnumerator IEnumerable.GetEnumerator()
    {
        this.GetEnumerator();
    }
}
8 голосов
/ 18 февраля 2009

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

Причина заключается в обратной совместимости с .NET 1.0 / 1.1, который не поддерживает дженерики.

4 голосов
/ 18 февраля 2009

Обычно GetEnumerator() вызывает GetEnumerator<T>(), поэтому не должно быть большой разницы в поведении. Что касается того, почему есть два метода, это сделано для обратной совместимости и для использования в ситуации, когда T не представляет большого интереса (или просто неизвестно).

2 голосов
/ 18 февраля 2009

Один общий, другой нет. Я считаю, что компилятор предпочитает использовать общую перегрузку.

...