tags:

views:

2255

answers:

6

Can anyone explain IEnumerable and IEnumerator to me?

for example, when to use it over foreach? what's the difference between IEnumerable and IEnumerator? Why do we need to use it?

+6  A: 

Implementing IEnumerable enables you to get an IEnumerator for a list.

IEnumerator allows foreach style sequential access to the items in the list, using the yield keyword.

Before foreach implementation (in Java 1.4, for example), the way to iterate a list was to get an enumerator from the list, then ask it for the "next" item in the list, for as long as the value returned as the next item is not null. Foreach simply does that implicitly as a language feature, in the same way that lock() implements the Monitor class behind the scenes.

I expect foreach works on lists because they implement IEnumerable.

Neil Barnwell
if its for a list why can't I just use foreach?
Seriously you downvoted me for this? Read up on foreach for more specific details. MSDN is probably the best source of info on this subject.
Neil Barnwell
@Neil, for what it's worth, I share your sentiment (perhaps better delete my response before that to gets downvoted)
Lieven
.Net duck types the foreach statement, but IEnumerable/IEnumerable<T> is the appropriate way to say that your class can be enumerated.
sixlettervariables
no i didnt downvote...
@ke42, appologies then for assuming it.
Lieven
I initially neg'd you one because all you had was "Implementing IEnumerable enables you to get an IEnumerator for a list." You've since edited your answer with more info, so I'm taking the neg away.
GregD
Well it won't let me take the neg away because "post is too old". Now unless you edited your answer again, you're stuck with my neg.
GregD
+3  A: 

Inheriting from IEnumerable means your class returns an IEnumerator object:

public class People : IEnumerable
{
    IEnumerator IEnumerable.GetEnumerator()
    {
  // return a PeopleEnumerator
    }
}

Inheriting from IEnumerator means your class returns the methods and properties for iteration:

public class PeopleEnumerator : IEnumerator
{
    public void Reset()...

    public bool MoveNext()...

    public object Current...
}

That's the difference anyway.

Chris
+4  A: 

An object implementing IEnumerable allows itself to visit each of its items through an enumerator. An object implementing IEnumerator is the doing the iteration. It's looping over an enumerable object.

Think of enumerable objects as of lists, stacks, trees.

Lieven
+3  A: 

Implementing IEnumerable essentially means that the object can be iterated over. This doesn't necessarily mean it is an array as there are certain lists that can't be indexed but you can enumerate them.

IEnumerator is the actual object used to perform the iterations. It controls moving from one object to the next in the list.

Most of the time, IEnumerable & IEnumerator are used transparently as part of a foreach loop.

Dan Herbert
+9  A: 

IEnumerable implements GetEnumerator. When called, that method will return an IEnumerator which implements MoveNext, Reset and Current.

Thus when your class implements IEnumerable, you are saying that you can call a method (GetEnumerator) and get a new object returned (an IEnumerator) you can use in a loop such as foreach.

DavGarcia
+13  A: 

for example, when to use it over foreach?

You don't use IEnumerable "over" foreach. Implementing IEnumerable makes using foreach possible.

When you write code like:

foreach (Foo bar in baz)
{
   ...
}

it's functionally equivalent to writing:

IEnumerator bat = baz.GetEnumerator();
while (bat.MoveNext())
{
   bar = (Foo)bat.Current()
   ...
}

By "functionally equivalent," I mean that's actually what the compiler turns the code into. You can't use foreach on baz in this example unless baz implements IEnumerable.

IEnumerable means that baz implements the method

IEnumerator GetEnumerator()

The IEnumerator object that this method returns must implement the methods

bool MoveNext()

and

Object Current()

The first method advances to the next object in the IEnumerable object that created the enumerator, returning false if it's done, and the second returns the current object.

Anything in .Net that you can iterate over implements IEnumerable. If you're building your own class, and it doesn't already inherit from a class that implements IEnumerable, you can make your class usable in foreach statements by implementing IEnumerable (and by creating an enumerator class that its new GetEnumerator method will return).

Robert Rossney
I think when the original poster said "over foreach", he meant "when should I call GetEnumerator() / MoveNext() explicitly instead of using a foreach loop." For what it's worth.
mquander
Ah, I think you're right. Well, the answer's implicit in my post: it doesn't matter, since that's what the compiler does anyway. So do what's easiest, i.e. use foreach.
Robert Rossney
excellent explanation!
Mahatma