Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any difference between iterator methods returning IEnumerable<T> and IEnumerator<T>?

Tags:

iterator

c#

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.

like image 276
Alexey Romanov Avatar asked Jan 06 '09 14:01

Alexey Romanov


2 Answers

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.

like image 104
casperOne Avatar answered Oct 12 '22 22:10

casperOne


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);
         }
    }
}
like image 24
John Gietzen Avatar answered Oct 12 '22 23:10

John Gietzen