Reputation: 170815
Consider two iterator methods with the same bodies:
public static IEnumerable<int> It1() {
...
}
public static IEnumerator<int> It2() {
...
}
Is there any circumstance where calling It2
is different from calling It1.GetEnumerator()
?
Is there ever a good reason to define an iterator as IEnumerator<T>
over IEnumerable<T>
? The only one I can think of is when you are implementing IEnumerable<T>.GetEnumerator()
.
EDIT: By iterator methods I mean methods using yield return
and yield break
constructs.
Upvotes: 7
Views: 518
Reputation: 49554
You would do this if you wanted to take charge of writing the IEnumerable<T>
wrapper class.
Let's say that you have a class that you want to do enumeration on, infinitely:
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);
}
}
}
Upvotes: 1
Reputation: 74540
As noted, you can't foreach
over an IEnumerator<T>
. Because of that, it makes it difficult to integrate into places in code where you want to iterate over what you are returning.
Also, the imporance here is that IEnumerable<T>
is meant to be a factory, so that you can produce implementations of IEnumerator<T>
that aren't directly tied to the implementation of the collection of T
.
Even more important now is the fact that all the extension methods for LINQ work off IEnumerable<T>
, so you will want to make your enumerations as easy to work with as possible by returning that.
Upvotes: 8