Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should I separately implement IEnumerator<T>?

In the framework classes of collections I have often seen IEnumerator<T> separately implemented as an inner class and an instance of it is returned in the GetEnumerator method.

Now suppose I'm writing my own collection classes which will have an inbuilt collection like List<T> or T[] act as the holder internally, say like this:

public class SpecialCollection<T> : IEnumerable<T>
{
    List<T> list;

    public SpecialCollection<T>()
    {

    }

    public IEnumerator<T> GetEnumerator()
    {
        return list.GetEnumerator();

        //or
        return list.Where(x => some logic).GetEnumerator(); 

        //or directly rely on yield keyword
        yield return x; //etc
    }
}

Should I be writing my own enumerator class, or is it ok to return enumerator of the List<T> class? Is there any circumstance under which should I be writing my own enumerator class?


I have a related question as well. If it's not all that important or doesn't make much of a difference, why do every collection class in the BCL write their own IEnumerator?

For eg, List<T> class has something like

T[] items;
public IEnumerator<T> GetEnumerator()
{
    return new List<T>.Enumerator(items);
}
like image 850
nawfal Avatar asked Jan 10 '23 10:01

nawfal


1 Answers

The answer to your first question is: when a yield return doesn't meet your needs.

The answer to your second question is: these heavily used types have performance requirements that are unusually strict, so the enumerators are custom built. I've written some articles on this recently; see:

http://ericlippert.com/2014/05/21/enumerator-advance/

http://ericlippert.com/2014/06/04/enumerator-bounds/

like image 158
Eric Lippert Avatar answered Jan 19 '23 01:01

Eric Lippert