C# Iterator Design Pattern

Link To source Code

This article will demonstrate the idea behind the Iteration pattern and simple implementation of it. The idea of the iterator pattern is to take the responsibility of accessing and passing trough the objects of the collection and put it in the iterator object. In C# Iterator pattern can be implemented simply using IEnumerable interface. Implementation of IEnumerable interface allows you to syntax sugar like foreach loop. This leads to the topic of collections.

In this post i’ll cover in more depth how Iterator is implemented by compiler. The iterator object will maintain the state of the iteration, keeping track of the current item and having a way of identifying what elements are next to be iterated. The abstraction provided by the iterator pattern allows you to modify the collection implementation without making any changes outside of collection.

This time you will see generic example of implementation, this is because i want to focus on the pattern functionality instead of  using techniques you may not know.

UML diagram

l6

 

Let’s start by creating interface for IIterator. Iterator Interface defines an interface for accessing and traversing elements.

interface IIterator
{
  int FirstItem { get; }
  int NextItem { get; }
  int CurrentItem { get; }
  bool IsDone { get; }
}

This will simulate looping through the objects of collection.

Implementation of this interface will make the iteration process clearer.  Implementation of this patter can be more difficult to understand because each Class is referring to the next one. Iterator need to have a reference to the IAggregate to create instance of it in the constructor, and use it later for returning its values.

Return value is set to int in Aggregate for this example.

class Iterator : IIterator
{
  IAggregate aggregate = null;

  //We need an index to track the iteration process
  int currentIndex = 0;

  public Iterator(IAggregate newAggregate)
  {
    aggregate = newAggregate;
  }
  //Returns item with index 0
  public int FirstItem
  {
    get
    {
      currentIndex = 0;
      return aggregate[currentIndex];
    }
  }

  //Returns next item
  public int NextItem
  {
   get
   {
     currentIndex += 1;

     if (IsDone == false)
     {
       return aggregate[currentIndex];
     }
     else
     {
       return -1;
     }
    }
  }

  public int CurrentItem
  {
    get
    {
       return aggregate[currentIndex];
    }
  }
//This method will give us feedabck when iteration ended
  public bool IsDone
  {
     get
     {
       if (currentIndex < aggregate.Count)
       {
          return false;
       }
       return true;
     }
   }
 }

 

Next interface to create is IAggregate.  One of the methods will return IIterator interface object.

 interface IAggregate
 {
   IIterator GetIterator();
   //This will handle manipulation of objects in the array
   int this[int itemIndex] { set; get; }
   int Count { get; }
 }

Implementation of this interface in Aggregate Class will be used as a place to create a list of an object that we will iterate through.

class Aggregate : IAggregate
{
  //Here is why Iterator methods returns integers;
  List<int> values = null;

  public Aggregate()
  {
    values = new List<int>();
  }

  public IIterator GetIterator()
  {
    //Iterator constructor takes IAggregate as parameter
    return new Iterator(this);
  }

  public int this[int itemIndex]
  {
    get
    {
      if (itemIndex < values.Count)
       {
           return values[itemIndex];
       }
      else
      {
        return -1;
      }
    }
    set
    {
        values.Add(value);
    }
   }

   public int Count
   {
     get
     {
       return values.Count;
     }
   }
 }

 

Last step is to create a Client that will create instance of Aggregate Class and Use Iterator to loop throug collection items.

class Program
{
  static void Main(string[] args)
  {
    Aggregate aggr = new Aggregate();

    aggr[0] = 7;
    aggr[1] = 8;
    aggr[2] = 9;
    aggr[3] = 89;

  IIterator iter = aggr.GetIterator();
  //Loops until isDone==false
    for (int i = iter.FirstItem; iter.IsDone == false; i = iter.NextItem)
    {
       Console.WriteLine(i.ToString());
    }
  Console.ReadLine();
  }
}

To conclude, Iteration pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation. In C# this can be handled just by implementing IEnumerable interface. I hope you learned something new today. In Next article I’ll cover one last design patterns. Stay Awesome!

PS: Thanks for all Up votes On Reddit.com! I can’t reply to  comments, because of shadow-ban :D