When I emplement IEnumerable<T>
interface I see two GetEnumerator
methods: one returning IEnumerator
and other IEnumerator<T>
. When would I use one or another?

- 89,048
- 55
- 235
- 380

- 1,347
- 3
- 17
- 24
5 Answers
You usually implement both. One is the newer, generic version that returns a typesafe enumerator (IEnumerator<T>
). The other one is for compatibility with Legacy code (returns IEnumerator
). A typical implementation is:
public IEnumerator<T> GetEnumerator() {
foreach(T item in items) {
yield return item;
}
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}

- 9,324
- 4
- 40
- 43
-
this one helped me a lot, avoiding the extra-class for the nested enumerator! – Nov 25 '09 at 07:17
-
+1. I also was googling to find a reference implementation that avoids the nested enumerator class and this was the first answer I came to. – quentin-starin Jul 20 '10 at 18:49
The reason there are two methods is because IEnumerable<T>
inherits the IEnumerable
interface so you are seeing the generic method from IEnumerable<T>
and the non-generic method from IEnumerable
.
Here is how you want to implement the interface in your type:
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();
}
}

- 9,324
- 4
- 40
- 43

- 344,730
- 71
- 640
- 635
If you are implementing the IEnumerable<T>
generic interface, you will pretty much always have to use the generic GetEnumerator method - unless you cast your object explicitly to (non-generic) IEnumerable.
The reason is backwards compatability with .NET 1.0/1.1 which didn't support generics.

- 118,853
- 40
- 150
- 176
Usually GetEnumerator()
calls GetEnumerator<T>()
, so there should not be much difference in behavior. As for why there are two methods, this is done for backwards compatibility and for use in situation where T
is not of great interest (or is just unknown).

- 113,561
- 39
- 200
- 288
The one is generic, the other one not. I believe the compiler prefers to use the generic overload.