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?
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?
Differences between IEnumerable and IEnumerator :
Whenever we pass IEnumerable collection to another function ,it doesn't know the current position of item/object(doesn't know which item its executing)
IEnumerable have one method GetEnumerator()
IEnumerator have one Property current and two methods Reset and MoveNext(Which is useful for knowing the current position of an item in a list).
IEnumerable and IEnumerator (and their generic counterparts IEnumerable<T> and IEnumerator<T>) are base interfaces of iterator implementations in .Net Framework Class Libray collections.
IEnumerable is the most common interface you would see in the majority of the code out there. It enables the foreach loop, generators (think yield) and because of its tiny interface, it's used to create tight abstractions. IEnumerable depends on IEnumerator.
IEnumerator, on the other hand, provides a slightly lower level iteration interface. It's referred to as the explicit iterator which gives the programmer more control over the iteration cycle.
IEnumerable
IEnumerable is a standard interface that enables iterating over collections that supports it (in fact, all collection types I can think of today implements IEnumerable). Compiler support allows language features like
foreach
. In general terms, it enables this implicit iterator implementation.foreach Loop
I think
foreach
loop is one of the main reasons for using IEnumerable interfaces.foreach
has a very succinct syntax and very easy to understand compared to classic C style for loops where you need to check the various variables to see what it was doing.yield Keyword
Probably a lesser known feature is that IEnumerable also enables generators in C# with the use of
yield return
andyield break
statements.Abstractions
Another common scenario in practice is using IEnumerable to provide minimalistic abstractions. Because it is a minuscule and read-only interface, you are encouraged to expose your collections as IEnumerable (rather than List for example). That way you are free to change your implementation without breaking your client's code (change List to a LinkedList for instance).
Gotcha
One behaviour to be aware of is that in streaming implementations (e.g. retrieving data row by row from a database, instead of loading all the results in memory first) you cannot iterate over the collection more than once. This is in contrast to in-memory collections like List, where you can iterate multiple times without problems. ReSharper, for example, has a code inspection for Possible multiple enumeration of IEnumerable.
IEnumerator
IEnumerator, on the other hand, is the behind the scenes interface which makes IEnumerble-foreach-magic work. Strictly speaking, it enables explicit iterators.
In my experience IEnumerator is rarely used in common scenarios due to its more verbose syntax and slightly confusing semantics (at least to me; e.g. MoveNext() returns a value as well, which the name doesn't suggest at all).
Use case for IEnumerator
I only used IEnumerator in particular (slightly lower level) libraries and frameworks where I was providing IEnumerable interfaces. One example is a data stream processing library which provided series of objects in a
foreach
loop even though behind the scenes data was collected using various file streams and serialisations.Client code
Library
I have noticed these differences:
A. We iterate the list in different way, foreach can be used for IEnumerable and while loop for IEnumerator.
B. IEnumerator can remember the current index when we pass from one method to another (it start working with current index) but IEnumerable can't remember the index and it reset the index to beginning. More in this video https://www.youtube.com/watch?v=jd3yUjGc9M0
Implementing IEnumerable means your class returns an IEnumerator object:
Implementing IEnumerator means your class returns the methods and properties for iteration:
That's the difference anyway.
A Minor contribution.
As many of them explain about 'when to use' and 'use with foreach'. I thought of adding Another States Difference here as requested in question about the difference between both IEnumerable an IEnumerator.
I created the below code sample based on the below discussion threads.
IEnumerable , IEnumerator vs foreach, when to use what What is the difference between IEnumerator and IEnumerable?
Enumerator preserves the state (iteration position) between function calls while iterations the other hand Enumerable does not.
Here is the tested example with comments to understand.
Experts please add/correct me.
The IEnumerable and IEnumerator Interfaces
To begin examining the process of implementing existing .NET interfaces, let’s first look at the role of IEnumerable and IEnumerator. Recall that C# supports a keyword named foreach that allows you to iterate over the contents of any array type:
While it might seem that only array types can make use of this construct, the truth of the matter is any type supporting a method named GetEnumerator() can be evaluated by the foreach construct.To illustrate, follow me!
Suppose we have a Garage class:
Ideally, it would be convenient to iterate over the Garage object’s subitems using the foreach construct, just like an array of data values:
Sadly, the compiler informs you that the Garage class does not implement a method named GetEnumerator(). This method is formalized by the IEnumerable interface, which is found lurking within the System.Collections namespace. Classes or structures that support this behavior advertise that they are able to expose contained subitems to the caller (in this example, the foreach keyword itself). Here is the definition of this standard .NET interface:
As you can see, the GetEnumerator() method returns a reference to yet another interface named System.Collections.IEnumerator. This interface provides the infrastructure to allow the caller to traverse the internal objects contained by the IEnumerable-compatible container:
If you want to update the Garage type to support these interfaces, you could take the long road and implement each method manually. While you are certainly free to provide customized versions of GetEnumerator(), MoveNext(), Current, and Reset(), there is a simpler way. As the System.Array type (as well as many other collection classes) already implements IEnumerable and IEnumerator, you can simply delegate the request to the System.Array as follows:
After you have updated your Garage type, you can safely use the type within the C# foreach construct. Furthermore, given that the GetEnumerator() method has been defined publicly, the object user could also interact with the IEnumerator type:
However, if you prefer to hide the functionality of IEnumerable from the object level, simply make use of explicit interface implementation:
By doing so, the casual object user will not find the Garage’s GetEnumerator() method, while the foreach construct will obtain the interface in the background when necessary.
Adapted from the Pro C# 5.0 and the .NET 4.5 Framework