.NET framework provides IEnumerable and IEnumerator interfaces to implement collectionlike behavior to user defined classes. A developer can implement these interfaces to provide collection like behavior to their classes. These interfaces are implemented through inner classes.
An inner class ( also known as Nested Type ) is a class which is enclosed inside another class.
class
A
{
int i ;
class B // Class B is a inner class or Nested Type
{
}
}
IEnumerator and IEnumerable interfaces are defined in System.Collections namespace as :
public
interface IEnumerable
{
IEnumerator GetEnumerator(); //Returns a Enumerator
}
public interface IEnumerator
{
bool MoveNext(); //An enumerator is always positioned before the
//first element of the collection, first call to MoveNext
//moves the enumerator over the first element of the
//collection
object Current { get ; } //Returns current object from the collection
void Reset(); //Resets enumerator to just above the first element of the collection.
}
For more details about above interfaces, refer Microsoft .NET framework documentation.
Above two interfaces must be implemented to provide a collection (similar to ArrayList ) like behavior to user defined classes. There is one more interface called Collection interface which I am excluding from our discussion.
To demonstrate the working of above interfaces and inner class I have created a class called ItemCollection which implements IEnumerable interface.
Within ItemCollection class there is one more class ( inner class or Nested Type ) called ItemIterator which implements IEnumerator interface. ItemCollection class also contains a string array itemId, which provides the basis for iteration.
For implementation details, see the code below and follow these steps :
1. Create a file ItemCollection.cs and save the source in that.
//File ItemCollection.cs
using System;
using System.Collections;
//Class ItemCollection implements IEnumerable interface
class ItemCollection : IEnumerable
{
String[] itemId ;
//Constructor to create and populate itemId String array
public ItemCollection( int noOfItem )
{
itemId = new String[noOfItem] ;
for(int i = 0; i < itemId.Length; i ++ )
{
itemId[i] = i.ToString();
}
}
//Implementation of method GetEnumerator of IEnumerable interface
public virtual IEnumerator GetEnumerator()
{
return new ItemIterator(this);
}
//Inner class ItemIterator, implements IEnumerator
public class ItemIterator : IEnumerator
{
//Declare a variable of type ItemCollection,
//to keep reference to enclosing class instance
private ItemCollection itemCollection;
//Declare a integer pointer and Set to -1, so that
//first call to MoveNext moves the enumerator over
//the first element of the collection.
private int index = -1 ;
//Pass an instance of enclosing class
public ItemIterator(ItemCollection ic)
{
//Save enclosing class reference
itemCollection = ic ;
}
//After an enumerator is created or after a Reset,
//an enumerator is positioned before the first element
//of the collection, and the first call to MoveNext
//moves the enumerator over the first element of the
//collection.
public bool MoveNext()
{
index++ ;
if( index < itemCollection.itemId.Length )
{
return true ;
}
else
{
index = -1;
return false;
}
}
//Return the current object, in our case Item Id string
//from itemId[] array. Throws InvalidOperationException exception
//if index pointing to wrong position
public object Current
{
get
{
if( index <= -1 )
{
throw new InvalidOperationException() ;
}
return itemCollection.itemId[index];
}
}
//Reset pointer to -1
public void Reset()
{
index = -1;
}
}
public static int Main(String[] args)
{
//Instantiate the collection
ItemCollection itemCol = new ItemCollection(10);
//Iterate the collection with various looping construct
//provided in c#
Console.WriteLine("1. Iteration using foreach loop:");
foreach( String itemIdStr in itemCol)
{
Console.Write(itemIdStr + " " );
}
Console.WriteLine("\n\n2. Iteration using for loop:");
for(IEnumerator ie = itemCol.GetEnumerator() ;
ie.MoveNext();)
{
Console.Write(ie.Current + " " );
}
Console.WriteLine("\n\n3. Iteration using while loop:");
IEnumerator ie1 = itemCol.GetEnumerator();
while(ie1.MoveNext())
{
Console.Write(ie1.Current + " ");
}
return 0;
}
}