126

Possible Duplicate:
Can anyone explain IEnumerable and IEnumerator to me?

What are the differences between IEnumerator and IEnumerable?

Community
  • 1
  • 1
  • 1
    Duplicate: http://stackoverflow.com/questions/558304/can-anyone-explain-ienumerable-and-ienumerator-to-me – Andrew Hare Mar 06 '09 at 18:02
  • 1
    This article might help you. https://www.c-sharpcorner.com/UploadFile/219d4d/ienumerable-vs-ienumerator-in-C-Sharp/ – Bimal Das Jun 29 '18 at 04:31

4 Answers4

134

IEnumerable is an interface that defines one method GetEnumerator which returns an IEnumerator interface, this in turn allows readonly access to a collection. A collection that implements IEnumerable can be used with a foreach statement.

Definition

IEnumerable 

public IEnumerator GetEnumerator();

IEnumerator

public object Current;
public void Reset();
public bool MoveNext();

example code from codebetter.com

cgreeno
  • 31,943
  • 7
  • 66
  • 87
  • 1
    This article might help you. https://www.c-sharpcorner.com/UploadFile/219d4d/ienumerable-vs-ienumerator-in-C-Sharp/ – Bimal Das Jun 29 '18 at 04:35
  • 2
    I would like to add that it is not an absolute requirement to implement `IEnumerable` to use the class with a `foreach` statement. Only a matching `IEnumerator GetEnumerator()` method is required. – rexcfnghk Sep 17 '18 at 03:36
  • 1
    The actual requirement for the foreach loop is even less restrictive and not bound to those interfaces at all. The compiler performs pattern matching. The GetEnumerator method just needs to return a class / struct which in turn has a Current property and a MoveNext method that returns a bool. I can highly recommend [Eric Lipperts blog post about pattern matching](https://blogs.msdn.microsoft.com/ericlippert/2011/06/30/following-the-pattern/) – Bunny83 Jul 30 '19 at 12:51
79

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.

Which do you use? The only reason to use IEnumerator is if you have something that has a nonstandard way of enumerating (that is, of returning its various elements one-by-one), and you need to define how that works. You'd create a new class implementing IEnumerator. But you'd still need to return that IEnumerator in an IEnumerable class.

For a look at what an enumerator (implementing IEnumerator<T>) looks like, see any Enumerator<T> class, such as the ones contained in List<T>, Queue<T>, or Stack<T>. For a look at a class implementing IEnumerable, see any standard collection class.

Ryan Lundy
  • 204,559
  • 37
  • 180
  • 211
  • 4
    Then why do we need this IEnumerable abstraction, if the only thing it does is just provide an access to Enumerator? Why don't just use Enumerator instead – madmanul Apr 11 '18 at 21:43
  • 12
    @xalz, they do two different things. `IEnumerable` answers the question: _Can_ I enumerate my elements? `IEnumerator` answers the question: _How_ do I enumerate my elements? If you have ten different collections that all enumerate the same way, you wouldn't want to have to define how each one enumerates separately. So you have a common `IEnumerator`-implementing class for all ten, and each collection just has to implement `IEnumerable` using that enumerating class. It's about separation of concerns, treating _holding_ data and _enumerating_ data as separate operations. – Ryan Lundy Apr 12 '18 at 08:00
  • 1
    This is the only answer that actually answered my question rather than listing differences between 2 classes. IEnumerator is a class that enumerates collections. A class that implements IEnumerable returns an IEnumerator. A class that implements IEnumerator has custom enumeration logic. – msteel9999 Jul 21 '22 at 10:17
21

An Enumerator shows you the items in a list or collection. Each instance of an Enumerator is at a certain position (the 1st element, the 7th element, etc) and can give you that element (IEnumerator.Current) or move to the next one (IEnumerator.MoveNext). When you write a foreach loop in C#, the compiler generates code that uses an Enumerator.

An Enumerable is a class that can give you Enumerators. It has a method called GetEnumerator which gives you an Enumerator that looks at its items. When you write a foreach loop in C#, the code that it generates calls GetEnumerator to create the Enumerator used by the loop.

John Smith
  • 7,243
  • 6
  • 49
  • 61
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
13

IEnumerable and IEnumerator are both interfaces. IEnumerable has just one method called GetEnumerator. This method returns (as all methods return something including void) another type which is an interface and that interface is IEnumerator. When you implement enumerator logic in any of your collection class, you implement IEnumerable (either generic or non generic). IEnumerable has just one method whereas IEnumerator has 2 methods (MoveNext and Reset) and a property Current. For easy understanding consider IEnumerable as a box that contains IEnumerator inside it (though not through inheritance or containment). See the code for better understanding:

class Test : IEnumerable, IEnumerator
{
    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }

    public object Current
    {
        get { throw new NotImplementedException(); }
    }

    public bool MoveNext()
    {
        throw new NotImplementedException();
    }

    public void Reset()
    {
        throw new NotImplementedException();
    }
}
PaulG
  • 13,871
  • 9
  • 56
  • 78
James Kingsbery
  • 7,298
  • 2
  • 38
  • 67