Does Class need to implement IEnumerable to use Foreach - c#

This is in C#, I have a class that I am using from some else's DLL. It does not implement IEnumerable but has 2 methods that pass back a IEnumerator. Is there a way I can use a foreach loop on these. The class I am using is sealed.

foreach does not require IEnumerable, contrary to popular belief. All it requires is a method GetEnumerator that returns any object that has the method MoveNext and the get-property Current with the appropriate signatures.
/EDIT: In your case, however, you're out of luck. You can trivially wrap your object, however, to make it enumerable:
class EnumerableWrapper {
private readonly TheObjectType obj;
public EnumerableWrapper(TheObjectType obj) {
this.obj = obj;
}
public IEnumerator<YourType> GetEnumerator() {
return obj.TheMethodReturningTheIEnumerator();
}
}
// Called like this:
foreach (var xyz in new EnumerableWrapper(yourObj))
…;
/EDIT: The following method, proposed by several people, does not work if the method returns an IEnumerator:
foreach (var yz in yourObj.MethodA())
…;

Re: If foreach doesn't require an explicit interface contract, does it find GetEnumerator using reflection?
(I can't comment since I don't have a high enough reputation.)
If you're implying runtime reflection then no. It does it all compiletime, another lesser known fact is that it also check to see if the returned object that might Implement IEnumerator is disposable.
To see this in action consider this (runnable) snippet.
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication3
{
class FakeIterator
{
int _count;
public FakeIterator(int count)
{
_count = count;
}
public string Current { get { return "Hello World!"; } }
public bool MoveNext()
{
if(_count-- > 0)
return true;
return false;
}
}
class FakeCollection
{
public FakeIterator GetEnumerator() { return new FakeIterator(3); }
}
class Program
{
static void Main(string[] args)
{
foreach (string value in new FakeCollection())
Console.WriteLine(value);
}
}
}

According to MSDN:
foreach (type identifier in expression) statement
where expression is:
Object collection or array expression.
The type of the collection element
must be convertible to the identifier
type. Do not use an expression that
evaluates to null. Evaluates to a type
that implements IEnumerable or a type
that declares a GetEnumerator method.
In the latter case, GetEnumerator
should either return a type that
implements IEnumerator or declares all
the methods defined in IEnumerator.

Short answer:
You need a class with a method named GetEnumerator, which returns the IEnumerator you already have. Achieve this with a simple wrapper:
class ForeachWrapper
{
private IEnumerator _enumerator;
public ForeachWrapper(Func<IEnumerator> enumerator)
{
_enumerator = enumerator;
}
public IEnumerator GetEnumerator()
{
return _enumerator();
}
}
Usage:
foreach (var element in new ForeachWrapper(x => myClass.MyEnumerator()))
{
...
}
From the C# Language Specification:
The compile-time processing of a
foreach statement first determines the
collection type, enumerator type and
element type of the expression. This
determination proceeds as follows:
If the type X of expression is an array type then there is an implicit
reference conversion from X to the
System.Collections.IEnumerable
interface (since System.Array
implements this interface). The
collection type is the
System.Collections.IEnumerable
interface, the enumerator type is the
System.Collections.IEnumerator
interface and the element type is the
element type of the array type X.
Otherwise, determine whether the type X has an appropriate
GetEnumerator method:
Perform member lookup on the type X with identifier GetEnumerator and no
type arguments. If the member lookup
does not produce a match, or it
produces an ambiguity, or produces a
match that is not a method group,
check for an enumerable interface as
described below. It is recommended
that a warning be issued if member
lookup produces anything except a
method group or no match.
Perform overload resolution using the resulting method group and an
empty argument list. If overload
resolution results in no applicable
methods, results in an ambiguity, or
results in a single best method but
that method is either static or not
public, check for an enumerable
interface as described below. It is
recommended that a warning be issued
if overload resolution produces
anything except an unambiguous public
instance method or no applicable
methods.
If the return type E of the GetEnumerator method is not a class,
struct or interface type, an error is
produced and no further steps are
taken.
Member lookup is performed on E with the identifier Current and no
type arguments. If the member lookup
produces no match, the result is an
error, or the result is anything
except a public instance property that
permits reading, an error is produced
and no further steps are taken.
Member lookup is performed on E with the identifier MoveNext and no
type arguments. If the member lookup
produces no match, the result is an
error, or the result is anything
except a method group, an error is
produced and no further steps are
taken.
Overload resolution is performed on the method group with an empty
argument list. If overload resolution
results in no applicable methods,
results in an ambiguity, or results in
a single best method but that method
is either static or not public, or its
return type is not bool, an error is
produced and no further steps are
taken.
The collection type is X, the enumerator type is E, and the element
type is the type of the Current
property.
Otherwise, check for an enumerable interface:
If there is exactly one type T such that there is an implicit
conversion from X to the interface
System.Collections.Generic.IEnumerable<T>,
then the collection type is this
interface, the enumerator type is the
interface
System.Collections.Generic.IEnumerator<T>,
and the element type is T.
Otherwise, if there is more than one such type T, then an error is
produced and no further steps are
taken.
Otherwise, if there is an implicit conversion from X to the
System.Collections.IEnumerable
interface, then the collection type is
this interface, the enumerator type is
the interface
System.Collections.IEnumerator, and
the element type is object.
Otherwise, an error is produced and no further steps are taken.

Not strictly. As long as the class has the required GetEnumerator, MoveNext, Reset, and Current members, it will work with foreach

No, you don't and you don't even need an GetEnumerator method, e.g.:
class Counter
{
public IEnumerable<int> Count(int max)
{
int i = 0;
while (i <= max)
{
yield return i;
i++;
}
yield break;
}
}
which is called this way:
Counter cnt = new Counter();
foreach (var i in cnt.Count(6))
{
Console.WriteLine(i);
}

You could always wrap it, and as an aside to be "foreachable" you only need to have a method called "GetEnumerator" with the proper signature.
class EnumerableAdapter
{
ExternalSillyClass _target;
public EnumerableAdapter(ExternalSillyClass target)
{
_target = target;
}
public IEnumerable GetEnumerator(){ return _target.SomeMethodThatGivesAnEnumerator(); }
}

Given class X with methods A and B that both return IEnumerable, you could use a foreach on the class like this:
foreach (object y in X.A())
{
//...
}
// or
foreach (object y in X.B())
{
//...
}
Presumably the meaning for the enumerables returned by A and B are well-defined.

#Brian: Not sure you try to loop over the value return from method call or the class itself,
If what you want is the class then by make it an array you can use with foreach.

For a class to be usable with foeach all it needs to do is have a public method that returns and IEnumerator named GetEnumerator(), that's it:
Take the following class, it doesn't implement IEnumerable or IEnumerator :
public class Foo
{
private int[] _someInts = { 1, 2, 3, 4, 5, 6 };
public IEnumerator GetEnumerator()
{
foreach (var item in _someInts)
{
yield return item;
}
}
}
alternatively the GetEnumerator() method could be written:
public IEnumerator GetEnumerator()
{
return _someInts.GetEnumerator();
}
When used in a foreach ( Note that the no wrapper is used, just a class instance ):
foreach (int item in new Foo())
{
Console.Write("{0,2}",item);
}
prints:
1 2 3 4 5 6

The type only requires to have a public/non-static/non-generic/parameterless method named GetEnumerator which should return something that has a public MoveNext method and a public Current property. As I recollect Mr Eric Lippert somewhere, this was designed so as to accommodate pre generic era for both type safety and boxing related performance issues in case of value types.
For instance this works:
class Test
{
public SomethingEnumerator GetEnumerator()
{
}
}
class SomethingEnumerator
{
public Something Current //could return anything
{
get { }
}
public bool MoveNext()
{
}
}
//now you can call
foreach (Something thing in new Test()) //type safe
{
}
This is then translated by the compiler to:
var enumerator = new Test().GetEnumerator();
try {
Something element; //pre C# 5
while (enumerator.MoveNext()) {
Something element; //post C# 5
element = (Something)enumerator.Current; //the cast!
statement;
}
}
finally {
IDisposable disposable = enumerator as System.IDisposable;
if (disposable != null) disposable.Dispose();
}
From 8.8.4 section of the spec.
Something worth noting is the enumerator precedence involved - it goes like if you have a public GetEnumerator method, then that is the default choice of foreach irrespective of who is implementing it. For example:
class Test : IEnumerable<int>
{
public SomethingEnumerator GetEnumerator()
{
//this one is called
}
IEnumerator<int> IEnumerable<int>.GetEnumerator()
{
}
}
(If you don't have a public implementation (ie only explicit implementation), then precedence goes like IEnumerator<T> > IEnumerator.)

Related

C# - Iteration works without explicit IEnumerable [duplicate]

This question already has answers here:
Duck typing in the C# compiler
(3 answers)
Closed 5 years ago.
the foreach in the following C# code works, even if I doesn't do Days:IEnumerable. So this looks like a kind of duck typing. Why is this possible? I thought Days:IEnumerable is obligatory.
using System;
using System.Collections;
using System.Collections.Generic;
namespace ConsoleApplication1
{
// works even if I does not
// Days:IEnumerable
public class Days
{
string[] tage = { "mon", "tue", "wed", "thu", "fri" };
public IEnumerator GetEnumerator()
{
for (int i = 0; i < tage.Length; i++)
yield return tage[i];
}
}
class Program
{
static void Main(string[] args)
{
Days daylist = new Days();
foreach (string s in daylist) { Console.WriteLine(s); }
}
}
}
According to the C# Language Specification, section 8.8.4 "The foreach statement" (https://msdn.microsoft.com/en-us/library/aa664754(v=vs.71).aspx)
The type of the expression of a foreach statement must be a collection type (as defined below) [...]
[...] A type C is said to be a collection type if it implements the System.Collections.IEnumerable interface or implements the collection pattern by meeting all of the following criteria:
C contains a public instance method with the signature GetEnumerator() that returns a struct-type, class-type, or interface-type, which is called E in the following text.
E contains a public instance method with the signature MoveNext() and the return type bool.
E contains a public instance property named Current that permits reading the current value. The type of this property is said to be the element type of the collection type.
So, not only your class is not obliged to implement IEnumerable, but also, your GetEnumerator() method is not obliged to return an IEnumerator. All that the returned type has to do is implement methods with the right signatures.
No, you don't need that interface. If you try to do a foreach on a non-enumerable data type, like bool, you get this error:
CS1579: foreach statement cannot operate on variables of type 'bool' because 'bool' does not contain a public definition for 'GetEnumerator'
So the requirement is simple: the class must have a public GetEnumerator method.
Then the next error tells us more:
CS0202: foreach requires that the return type 'void' of 'Program.C.GetEnumerator()' must have a suitable public MoveNext method and public Current property
So this is a valid implementation to use foreach, while it is unlike the call will ever end ;)
public class E
{
public bool MoveNext() { return true; }
public object Current { get { return null; } }
}
public class C
{
public E GetEnumerator()
{
return new E();
}
}
Like you said, this benefits from Duck Typing the interface is not mandatory. See MSDN thorough article on the topic.
https://msdn.microsoft.com/en-us/magazine/mt797654.aspx

C# `foreach` behaviour — Clarification?

I've read Eric's article here about foreach enumeration and about the different scenarios where foreach can work
In order to prevent the old C# version to do boxing , the C# team enabled duck typing for foreach to run on a non- Ienumerable collection.(A public GetEnumerator that return something that has public MoveNext and Current property is sufficient(.
So , Eric wrote a sample :
class MyIntegers : IEnumerable
{
public class MyEnumerator : IEnumerator
{
private int index = 0;
object IEnumerator.Current { return this.Current; }
int Current { return index * index; }
public bool MoveNext()
{
if (index > 10) return false;
++index;
return true;
}
}
public MyEnumerator GetEnumerator() { return new MyEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }
}
But I believe it has some typos (missing get accessor at Current property implementation) which prevent it from compiling (I've already Emailed him).
Anyway here is a working version :
class MyIntegers : IEnumerable
{
public class MyEnumerator : IEnumerator
{
private int index = 0;
public void Reset()
{
throw new NotImplementedException();
}
object IEnumerator.Current {
get { return this.Current; }
}
int Current {
get { return index*index; }
}
public bool MoveNext()
{
if (index > 10) return false;
++index;
return true;
}
}
public MyEnumerator GetEnumerator() { return new MyEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }
}
Ok.
According to MSDN :
A type C is said to be a collection type if it implements the
System.Collections.IEnumerable interface or implements the
collection pattern by meeting all of the following criteria:
C contains a public instance method with the signature GetEnumerator() that returns a struct-type, class-type, or interface-type, which is called E in the following text.
E contains a public instance method with the signature MoveNext() and the return type bool.
E contains a public instance property named Current that permits reading the current value. The type of this property is said to be the element type of the collection type.
OK. Let's match the docs to Eric's sample
Eric's sample is said to be a collection type because it does implements the System.Collections.IEnumerable interface ( explicitly though). But it is not(!) a collection pattern because of bullet 3 : MyEnumerator does not public instance property named Current.
MSDN says :
If the collection expression is of a type that implements the
collection pattern (as defined above), the expansion of the foreach
statement is:
E enumerator = (collection).GetEnumerator();
try {
while (enumerator.MoveNext()) {
ElementType element = (ElementType)enumerator.Current;
statement;
}
}
finally {
IDisposable disposable = enumerator as System.IDisposable;
if (disposable != null) disposable.Dispose();
}
Otherwise , The collection expression is of a type that implements
System.IEnumerable (!), and the expansion of the foreach statement is:
IEnumerator enumerator =
((System.Collections.IEnumerable)(collection)).GetEnumerator();
try {
while (enumerator.MoveNext()) {
ElementType element = (ElementType)enumerator.Current;
statement;
}
}
finally {
IDisposable disposable = enumerator as System.IDisposable;
if (disposable != null) disposable.Dispose();
}
Question #1
It seems that Eric's sample neither implements the
collection pattern nor System.IEnumerable - so it's not supposed to match any of the condition specified above. So how come I can still iterate it via :
foreach (var element in (new MyIntegers() as IEnumerable ))
{
Console.WriteLine(element);
}
Question #2
Why do I have to mention new MyIntegers() as IEnumerable ? it's already Ienumerable (!!) and even after that , Isn't the compiler is already doing the job by itself via casting :
((System.Collections.IEnumerable)(collection)).GetEnumerator() ?
It is right here :
IEnumerator enumerator =
((System.Collections.IEnumerable)(collection)).GetEnumerator();
try {
while (enumerator.MoveNext()) {
...
So why it still wants me to mention as Ienumerable ?
MyEnumerator does not has the required public methods
Yes it does - or rather, it would if Current were public. All that's required is that it has:
A public, readable Current property
A public MoveNext() method with no type arguments returning bool
The lack of public here was just another typo, basically. As it is, the example doesn't do what it's meant to (prevent boxing). It's using the IEnumerable implementation because you're using new MyIntegers() as IEnumerable - so the expression type is IEnumerable, and it just uses the interface throughout.
You claim that it doesn't implement IEnumerable, (which is System.Collections.IEnumerable, btw) but it does, using explicit interface implementation.
It's easiest to test this sort of thing without implementing IEnumerable at all:
using System;
class BizarreCollection
{
public Enumerator GetEnumerator()
{
return new Enumerator();
}
public class Enumerator
{
private int index = 0;
public bool MoveNext()
{
if (index == 10)
{
return false;
}
index++;
return true;
}
public int Current { get { return index; } }
}
}
class Test
{
static void Main(string[] args)
{
foreach (var item in new BizarreCollection())
{
Console.WriteLine(item);
}
}
}
Now if you make Current private, it won't compile.
The reference to System.IEnumerable on the MSDN is nothing more than a typo in an old language specification, no such interface exists, I believe it should be referring to System.Collections.IEnumerable.
You should really read the language specification of the version of C# you are using, the C# 5.0 language specification is available here.
Some further information about why failing to cast this example results in an error rather than falling back to using System.Collections.IEnumerable:
In the specification for foreach (section 8.8.4) you will see the rules have slightly changed (some steps have been cut for brevity):
Perform member lookup on the type X with identifier GetEnumerator and no type arguments. If the member lookup does not produce a match, or it produces an ambiguity, or produces a match that is not a method group, check for an enumerable interface as described below. It is recommended that a warning be issued if member lookup produces anything except a method group or no match.
Perform overload resolution using the resulting method group and an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, check for an enumerable interface as described below. It is recommended that a warning be issued if overload resolution produces anything except an unambiguous public instance method or no applicable methods.
If the return type E of the GetEnumerator method is not a class, struct or interface type, an error is produced and no further steps are taken.
Member lookup is performed on E with the identifier Current and no type arguments. If the member lookup produces no match, the result is an error, or the result is anything except a public instance property that permits reading, an error is produced and no further steps are taken.
The collection type is X, the enumerator type is E, and the element type is the type of the Current property.
So from the first bullet point we would find the public MyEnumerator GetEnumerator(), the second and third bullets go through without error. When we get to the fourth bullet point, no public member called Current is available which results in the error you are seeing without the cast, this exact situation never gives the compiler the opportunity to look for the enumerable interface.
When you explicitly cast your instance to an IEnumerable all of the requirements are satisfied as the type IEnumerable and the associated IEnumerator satisfy all of the requirements.
Also from the documentation:
The above steps, if successful, unambiguously produce a collection type C, enumerator type E and element type T. A foreach statement of the form
foreach (V v in x) embedded-statement
is then expanded to:
{
E e = ((C)(x)).GetEnumerator();
try {
while (e.MoveNext()) {
V v = (V)(T)e.Current;
embedded-statement
}
}
finally {
… // Dispose e
}
}
So given your explicit cast to IEnumerable, you will end up with the following:
C = System.Collections.IEnumerable
x = new MyIntegers() as System.Collections.IEnumerable
E = System.Collections.IEnumerator
T = System.Object
V = System.Object
{
System.Collections.IEnumerator e = ((System.Collections.IEnumerable)(new MyIntegers() as System.Collections.IEnumerable)).GetEnumerator();
try {
while (e.MoveNext()) {
System.Object element = (System.Object)(System.Object)e.Current;
Console.WriteLine(element);
}
}
finally {
System.IDisposable d = e as System.IDisposable;
if (d != null) d.Dispose();
}
}
Which explains why using the cast works.

GetIterator() and the iterator pattern

I'm trying to implement the Iterator pattern.
Basically, from what I understand, it makes a class "foreachble" and makes the code more secure by not revealing the exact collection type to the user.
I have been experimenting a bit and I found out that if I implement
IEnumerator GetEnumerator() in my class, I get the desired result ... seemingly sparing the headache of messing around with realizing interfaces.
Here is a glimpse to what I mean:
public class ListUserLoggedIn
{
/*
stuff
*/
public List<UserLoggedIn> UserList { get; set; }
public IEnumerator<UserLoggedIn> GetEnumerator()
{
foreach (UserLoggedIn user in this.UserList)
{
yield return user;
}
}
public void traverse()
{
foreach (var item in ListUserLoggedIn.Instance)
{
Console.Write(item.Id);
}
}
}
I guess my question is, is this a valid example of Iterator?
If yes, why is this working, and what can I do to make the iterator return only a part or an anonymous object via "var".
If not, what is the correct way ...
First a smaller and simplified self-contained version:
class Program
{
public IEnumerator<int> GetEnumerator() // IEnumerable<int> works too.
{
for (int i = 0; i < 5; i++)
yield return i;
}
static void Main(string[] args)
{
var p = new Program();
foreach (int x in p)
{
Console.WriteLine(x);
}
}
}
And the 'strange' thing here is that class Program does not implement IEnumerable.
The specs from Ecma-334 say:
§ 8.18 Iterators
The foreach statement is used to iterate over the elements of an enumerable collection. In order to be enumerable, a collection shall have a parameterless GetEnumerator method that returns an enumerator.
So that's why foreach() works on your class. No mention of IEnumerable. But how does the GetEnumerator() produce something that implements Current and MoveNext ? From the same section:
An iterator is a statement block that yields an ordered sequence of values. An iterator is distinguished from a normal statement block by the presence of one or more yield statements
It is important to understand that an iterator is not a kind of member, but is a means of implementing a function member
So the body of your method is an iterator-block, the compiler checks a number of constraints (the method must return an IEnumerable or IEnumerator) and then implements the IEnumerator members for you.
And to the deeper "why", I just learned something too. Based on an annotation by Eric Lippert in "The C# Programming Language 3rd", page 369:
This is called the "pattern-based approach" and it dates from before generics. An interface based approach in C#1 would have been totally based on passing object around and value types would always have had to be boxed. The pattern approach allows
foreach (int x in myIntCollection)
without generics and without boxing. Neat.

What kind of class does yield return return

So I've notice that this code works:
class Program
{
public static void Main()
{
Int32[ ]numbers = {1,2,3,4,5};
using (var enumerator = Data().GetEnumerator())
{
}
}
public static IEnumerable<String> Data()
{
yield return "Something";
}
}
In particular, I'm curious about the using block, since:
Int32[] numbers = { 1, 2, 3, 4, 5, 6 };
using (var enumerator = numbers.GetEnumerator())
{
}
fails with a compiler error. Obviously, the class that yield return returns is IDisposable while a regular array enumerator is not. So now I'm curious: what exactly does yield return create?
IEnumerator<T> implements IDisposable, as you can see in the Object Browser or in MSDN.
The non-generic IEnumerator does not.
The base Array class implements IEnumerable but not IEnumerable<T>. (since Array is not generic)
Concrete array types do implement IEnumerable<T>, but they implement GetEnumerator() explicitly (I'm not sure why).
Therefore, the GetEnumerator() visible on any array type returns IEnumerator.
The generic IEnumerable<T> implementation returns a System.SZArrayHelper.SZGenericArrayEnumerator<T>.
The source code for this class (in Array.cs) has the following comment which partially explains this (remember, all support for generic arrays dates back to a time when IEnumerable<T> was not contraviant)
//---------------------------------------------------------------------------------------
// ! READ THIS BEFORE YOU WORK ON THIS CLASS.
//
// The methods on this class must be written VERY carefully to avoid introducing security holes.
// That's because they are invoked with special "this"! The "this" object
// for all of these methods are not SZArrayHelper objects. Rather, they are of type U[]
// where U[] is castable to T[]. No actual SZArrayHelper object is ever instantiated. Thus, you will
// see a lot of expressions that cast "this" "T[]".
//
// This class is needed to allow an SZ array of type T[] to expose IList<T>,
// IList<T.BaseType>, etc., etc. all the way up to IList<Object>. When the following call is
// made:
//
// ((IList<T>) (new U[n])).SomeIListMethod()
//
// the interface stub dispatcher treats this as a special case, loads up SZArrayHelper,
// finds the corresponding generic method (matched simply by method name), instantiates
// it for type <T> and executes it.
//
// The "T" will reflect the interface used to invoke the method. The actual runtime "this" will be
// array that is castable to "T[]" (i.e. for primitivs and valuetypes, it will be exactly
// "T[]" - for orefs, it may be a "U[]" where U derives from T.)
//---------------------------------------------------------------------------------------

Can anyone explain IEnumerable and IEnumerator to me? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
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?
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).
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:
// Iterate over an array of items.
int[] myArrayOfInts = {10, 20, 30, 40};
foreach(int i in myArrayOfInts)
{
Console.WriteLine(i);
}
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:
// Garage contains a set of Car objects.
public class Garage
{
private Car[] carArray = new Car[4];
// Fill with some Car objects upon startup.
public Garage()
{
carArray[0] = new Car("Rusty", 30);
carArray[1] = new Car("Clunker", 55);
carArray[2] = new Car("Zippy", 30);
carArray[3] = new Car("Fred", 30);
}
}
Ideally, it would be convenient to iterate over the Garage object’s subitems using the foreach
construct, just like an array of data values:
// This seems reasonable ...
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("***** Fun with IEnumerable / IEnumerator *****\n");
Garage carLot = new Garage();
// Hand over each car in the collection?
foreach (Car c in carLot)
{
Console.WriteLine("{0} is going {1} MPH",
c.PetName, c.CurrentSpeed);
}
Console.ReadLine();
}
}
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:
// This interface informs the caller
// that the object's subitems can be enumerated.
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
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:
// This interface allows the caller to
// obtain a container's subitems.
public interface IEnumerator
{
bool MoveNext (); // Advance the internal position of the cursor.
object Current { get;} // Get the current item (read-only property).
void Reset (); // Reset the cursor before the first member.
}
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:
using System.Collections;
...
public class Garage : IEnumerable
{
// System.Array already implements IEnumerator!
private Car[] carArray = new Car[4];
public Garage()
{
carArray[0] = new Car("FeeFee", 200);
carArray[1] = new Car("Clunker", 90);
carArray[2] = new Car("Zippy", 30);
carArray[3] = new Car("Fred", 30);
}
public IEnumerator GetEnumerator()
{
// Return the array object's IEnumerator.
return carArray.GetEnumerator();
}
}
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:
// Manually work with IEnumerator.
IEnumerator i = carLot.GetEnumerator();
i.MoveNext();
Car myCar = (Car)i.Current;
Console.WriteLine("{0} is going {1} MPH", myCar.PetName, myCar.CurrentSpeed);
However, if you prefer to hide the functionality of IEnumerable from the object level, simply make
use of explicit interface implementation:
IEnumerator IEnumerable.GetEnumerator()
{
// Return the array object's IEnumerator.
return carArray.GetEnumerator();
}
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
Implementing IEnumerable means your class returns an IEnumerator object:
public class People : IEnumerable
{
IEnumerator IEnumerable.GetEnumerator()
{
// return a PeopleEnumerator
}
}
Implementing 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.
Explanation via Analogy + Code Walkthrough
Analogy: Imagine you are a detective on an aeroplane . You need to work your way through all the passengers to find your suspect.
An aeroplane can only do this, if it is:
countable, and
if it has a counter.
What does countable mean?
If an airline is "countable", this means that there MUST be a flight attendant present on the plane, whose sole job is to count:
The counter/flight attendant MUST start before the first passenger 2. (i.e. the flight attendant) MUST "move next" up the aisle to the first seat.
He/she is to then record: (i) who the person is in the seat, and (ii) their current location in the aisle.
The counter keeps going till he reaches the end of the plane.
Let's tie this with the IEnumerables
foreach (Passenger passenger in Plane)
// the airline hostess is now at the front of the plane
// and slowly making her way towards the back
// when she get to a particular passenger she gets some information
// about the passenger and then immediately heads to the cabin
// to let the captain decide what to do with it
{ // <---------- Note the curly bracket that is here.
// we are now cockpit of the plane with the captain.
// the captain wants to give the passenger free
// champaign if they support manchester city
if (passenger.supports_mancestercity())
{
passenger.getFreeChampaign();
}
else
{
// you get nothing! GOOD DAY SIR!
}
} // <---- Note the curly bracket that is here!
// the hostess has delivered the information
// to the captain and goes to the next person
// on the plane (if she has not reached the
// end of the plane)
Summary
In other words, something is countable if it has a counter. And counter must (basically): (i) remember its place (state), (ii) be able to move next, (iii) and know about the current person he is dealing with.
Enumerable is just a fancy word for "countable".
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.
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.
An object implementing IEnumerable allows others to visit each of its items (by 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.
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
foreach (var value in list)
Console.WriteLine(value);
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 and yield break statements.
IEnumerable<Thing> GetThings() {
if (isNotReady) yield break;
while (thereIsMore)
yield return GetOneMoreThing();
}
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.
var iter = list.GetEnumerator();
while (iter.MoveNext())
Console.WriteLine(iter.Current);
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
foreach(var item in feed.GetItems())
Console.WriteLine(item);
Library
IEnumerable GetItems() {
return new FeedIterator(_fileNames)
}
class FeedIterator: IEnumerable {
IEnumerator GetEnumerator() {
return new FeedExplicitIterator(_stream);
}
}
class FeedExplicitIterator: IEnumerator {
DataItem _current;
bool MoveNext() {
_current = ReadMoreFromStream();
return _current != null;
}
DataItem Current() {
return _current;
}
}
Differences between IEnumerable and IEnumerator :
IEnumerable uses IEnumerator internally.
IEnumerable doesn't know which item/object is executing.
Whenever we pass IEnumerator to another function, it knows the current position of item/object.
Whenever we pass an 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()
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
IEnumerator has one property called Current and two methods, Reset() and MoveNext() (which is useful for knowing the current position of an item in a list).
public interface IEnumerator
{
object Current { get; }
bool MoveNext();
void Reset();
}
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.
IEnumerable is a box that contains Ienumerator. IEnumerable is base interface for all the collections. foreach loop can operate if the collection implements IEnumerable. In the below code it explains the step of having our own Enumerator. Lets first define our Class of which we are going to make the collection.
public class Customer
{
public String Name { get; set; }
public String City { get; set; }
public long Mobile { get; set; }
public double Amount { get; set; }
}
Now we will define the Class which will act as a collection for our class Customer. Notice that it is implementing the interface IEnumerable. So that we have to implement the method GetEnumerator. This will return our custom Enumerator.
public class CustomerList : IEnumerable
{
Customer[] customers = new Customer[4];
public CustomerList()
{
customers[0] = new Customer { Name = "Bijay Thapa", City = "LA", Mobile = 9841639665, Amount = 89.45 };
customers[1] = new Customer { Name = "Jack", City = "NYC", Mobile = 9175869002, Amount = 426.00 };
customers[2] = new Customer { Name = "Anil min", City = "Kathmandu", Mobile = 9173694005, Amount = 5896.20 };
customers[3] = new Customer { Name = "Jim sin", City = "Delhi", Mobile = 64214556002, Amount = 596.20 };
}
public int Count()
{
return customers.Count();
}
public Customer this[int index]
{
get
{
return customers[index];
}
}
public IEnumerator GetEnumerator()
{
return customers.GetEnumerator(); // we can do this but we are going to make our own Enumerator
return new CustomerEnumerator(this);
}
}
Now we are going to create our own custom Enumerator as follow. So, we have to implement method MoveNext.
public class CustomerEnumerator : IEnumerator
{
CustomerList coll;
Customer CurrentCustomer;
int currentIndex;
public CustomerEnumerator(CustomerList customerList)
{
coll = customerList;
currentIndex = -1;
}
public object Current => CurrentCustomer;
public bool MoveNext()
{
if ((currentIndex++) >= coll.Count() - 1)
return false;
else
CurrentCustomer = coll[currentIndex];
return true;
}
public void Reset()
{
// we dont have to implement this method.
}
}
Now we can use foreach loop over our collection like below;
class EnumeratorExample
{
static void Main(String[] args)
{
CustomerList custList = new CustomerList();
foreach (Customer cust in custList)
{
Console.WriteLine("Customer Name:"+cust.Name + " City Name:" + cust.City + " Mobile Number:" + cust.Amount);
}
Console.Read();
}
}
An understanding of the Iterator pattern will be helpful for you. I recommend reading the same.
Iterator Pattern
At a high level the iterator pattern can be used to provide a standard way of iterating through collections of any type.
We have 3 participants in the iterator pattern, the actual collection (client), the aggregator and the iterator. The aggregate is an interface/abstract class that has a method that returns an iterator. Iterator is an interface/abstract class that has methods allowing us to iterate through a collection.
In order to implement the pattern we first need to implement an iterator to produce a concrete that can iterate over the concerned collection (client)
Then the collection (client) implements the aggregator to return an instance of the above iterator.
Here is the UML diagram
So basically in c#, IEnumerable is the abstract aggregate and IEnumerator is the abstract Iterator. IEnumerable has a single method GetEnumerator that is responsible for creating an instance of IEnumerator of the desired type. Collections like Lists implement the IEnumerable.
Example.
Lets suppose that we have a method getPermutations(inputString) that returns all the permutations of a string and that the method returns an instance of IEnumerable<string>
In order to count the number of permutations we could do something like the below.
int count = 0;
var permutations = perm.getPermutations(inputString);
foreach (string permutation in permutations)
{
count++;
}
The c# compiler more or less converts the above to
using (var permutationIterator = perm.getPermutations(input).GetEnumerator())
{
while (permutationIterator.MoveNext())
{
count++;
}
}
If you have any questions please don't hesitate to ask.
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.
static void EnumerableVsEnumeratorStateTest()
{
IList<int> numList = new List<int>();
numList.Add(1);
numList.Add(2);
numList.Add(3);
numList.Add(4);
numList.Add(5);
numList.Add(6);
Console.WriteLine("Using Enumerator - Remembers the state");
IterateFrom1to3(numList.GetEnumerator());
Console.WriteLine("Using Enumerable - Does not Remembers the state");
IterateFrom1to3Eb(numList);
Console.WriteLine("Using Enumerable - 2nd functions start from the item 1 in the collection");
}
static void IterateFrom1to3(IEnumerator<int> numColl)
{
while (numColl.MoveNext())
{
Console.WriteLine(numColl.Current.ToString());
if (numColl.Current > 3)
{
// This method called 3 times for 3 items (4,5,6) in the collection.
// It remembers the state and displays the continued values.
IterateFrom3to6(numColl);
}
}
}
static void IterateFrom3to6(IEnumerator<int> numColl)
{
while (numColl.MoveNext())
{
Console.WriteLine(numColl.Current.ToString());
}
}
static void IterateFrom1to3Eb(IEnumerable<int> numColl)
{
foreach (int num in numColl)
{
Console.WriteLine(num.ToString());
if (num>= 5)
{
// The below method invokes for the last 2 items.
//Since it doesnot persists the state it will displays entire collection 2 times.
IterateFrom3to6Eb(numColl);
}
}
}
static void IterateFrom3to6Eb(IEnumerable<int> numColl)
{
Console.WriteLine();
foreach (int num in numColl)
{
Console.WriteLine(num.ToString());
}
}
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
IEnumerable and IEnumerator both are interfaces in C#.
IEnumerable is an interface defining a single method GetEnumerator() that returns an IEnumerator interface.
This works for read-only access to a collection that implements that IEnumerable can be used with a foreach statement.
IEnumerator has two methods, MoveNext and Reset. It also has a property called Current.
The following shows the implementation of IEnumerable and IEnumerator.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Enudemo
{
class Person
{
string name = "";
int roll;
public Person(string name, int roll)
{
this.name = name;
this.roll = roll;
}
public override string ToString()
{
return string.Format("Name : " + name + "\t Roll : " + roll);
}
}
class Demo : IEnumerable
{
ArrayList list1 = new ArrayList();
public Demo()
{
list1.Add(new Person("Shahriar", 332));
list1.Add(new Person("Sujon", 333));
list1.Add(new Person("Sumona", 334));
list1.Add(new Person("Shakil", 335));
list1.Add(new Person("Shruti", 336));
}
IEnumerator IEnumerable.GetEnumerator()
{
return list1.GetEnumerator();
}
}
class Program
{
static void Main(string[] args)
{
Demo d = new Demo(); // Notice here. it is simple object but for
//IEnumerator you can get the collection data
foreach (Person X in d)
{
Console.WriteLine(X);
}
Console.ReadKey();
}
}
}
/*
Output :
Name : Shahriar Roll : 332
Name : Sujon Roll : 333
Name : Sumona Roll : 334
Name : Shakil Roll : 335
Name : Shruti Roll : 336
*/

Categories