When implementing iterator using yield return
, is there any difference between returning IEnumerator
and IEnumerable
?
An IEnumerator is a thing that can enumerate: it has the Current property and the MoveNext and Reset methods (which in . NET code you probably won't call explicitly, though you could). An IEnumerable is a thing that can be enumerated...which simply means that it has a GetEnumerator method that returns an IEnumerator .
The IEnumerable interface declares only one method called GetEnumerator which returns another type of interface called the IEnumerator interface for that particular collection. IEnumerator, on the other hand, is the base interface for all non-generic enumerators which are used to read the data in the collection.
IEnumerator is an interface, which when implemented allows you to iterate through the list of controls. To implement it requires that you provide two methods - Reset to go back to the beginning of the list, and MoveNext to move forward, and Current to get the current item.
IEnumerable in C# is an interface that defines one method, GetEnumerator which returns an IEnumerator interface. This allows readonly access to a collection then a collection that implements IEnumerable can be used with a for-each statement.
IEnumerable
and IEnumerator
are two different things.
IEnumerable<T>
is a sequence that can be iterated over.
IEnumerator<T>
is an object that is returned by IEnumerable<T>
to iterate once over the sequence.
In general, the only place to return IEnumerator<T>
is in the GetEnumerator()
method.
yield return
behaves the same way for both types, except that an iterator method that returns IEnumerable<T>
can execute multiple times (each time the sequence is enumerated).
For more information on how this works, see Jon Skeet's article.
As the implementer of the iterator function, it doesn't have an effect on you. It matters more to the consumer of the iterator function.
In general, people prefer to have an IEnumerable<T>
object, because you can do a foreach loop on it, and if you really need an IEnumerator<T>
object, then you can get one from the IEnumerable<T>
object's GetEnumerator()
method.
As mentioned by SLaks, an Enumerator can be iterated over once, and an IEnumerable can generate any number of Enumerators, allowing the underlying collection to be iterated over multiple times.
In practice, the primary difference is that there are lots and lots of methods, such as LINQ, and many methods for interacting with collections that all deal with Enumerables, not Enumerators, so an Enumerator simply won't be able to be as widely used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With