yield, IEnumerator, IEnumerable,... confused?... well let me explain: -
An IEnumerator provides a way to iterate through a collection which would contain two methods: MoveNext() - to advance to the next element & Current() - to get the value at the current position
An IEnumerable is nothing but an object which can be iterated. i.e. you can call
GetEnumerator()
to get an IEnumerator which can be used to enumerate it.
Implementation of and IEnumerable using an IEnumerator would look something like shown below:
class MyEnumerableClass : IEnumerable
{
private string[] myList;
public MyEnumerableClass(string[] iList)
{
myList = new string[iList.Length];
for(int counter = 0;counter< iList.Length;counter++)
myList[counter] = iList[counter];
}
public IEnumerator GetEnumerator()
{
return new MyEnumeratorClass(myList);
}
}
class MyEnumeratorClass : IEnumerator
{
private string[] myList;
int position = -1;
public MyEnumeratorClass(string[] iList)
{
myList = iList;
}
public object Current
{
get
{
return myList[position];
}
}
public bool MoveNext()
{
position++;
return (position < myList.Length);
}
public void Reset()
{
position = -1;
}
}
class Program
{
static void Main()
{
MyEnumerableClass p = new MyEnumerableClass(new string[] { "albert", "issac", "thomas" });
foreach (string item in p)
Console.WriteLine(item);
}
}
Then came along the yield operator, and suddenly all the plumbing work is no longer required. The same above functionality could be implemented as shown below.
class MyEnumerableClass : IEnumerable
{
private string[] myList;
public MyEnumerableClass(string[] iList)
{
myList = iList;
}
public IEnumerator GetEnumerator()
{
foreach (string s in myList)
yield return s;
}
}
class Program
{
static void Main()
{
MyEnumerableClass p = new MyEnumerableClass(new string[] { "albert", "issac", "thomas" });
foreach (string item in p)
Console.WriteLine(item);
}
}
Now, though this seems really amazing is actually quite simple to explain. When we use the yield keyword, the compiler in fact creates an enumerator class that keeps the current state of iteration. This class implements all the methods and properties of the IEnumerator i.e. MoveNext, Reset and Current.
One nice implementation of IEnumerable is given in the link: Fibonacci Series using an IEnumerable class