Iterator Design Pattern in C#

Iterator Design Pattern in C# with Example

In this article, I am going to discuss the Iterator Design Pattern in C# with examples. Please read our previous article where we discussed the basics of Behavioural Design Patterns in C#. The Iterator Design Pattern falls under the category of Behavioral Design Pattern. As part of this article, we are going to discuss the following pointers.

  1. What is Iterator Design Pattern?
  2. Example to understand the Iterator Design Pattern in C#.
  3. When to use the Iterator Design Pattern in C#?
What is Iterator Design Pattern?

The Iterator Design Pattern in C# allows sequential access of elements without exposing the inside logic. That means using the Iterator Design Pattern we can access the elements of a collection object in a sequential manner without any need to know its internal representations.

The collections (List, Array List, Array, etc.) are nothing but a container that contains lots of objects. In object-oriented programming, the iterator pattern is a design pattern in which an iterator is used to traverse a container and access the elements of the container. Please have a look at the following image.

Iterator Design Pattern in C#

The Data structure of List will be different from the Data Structure of ArrayList and the same in the case of Array. The storing mechanism of List will be different from the storing mechanism of Array as well as different from ArrayList.

So the main use of the Iterator design pattern is to access the elements (object1, object2, object3, and object4) of a collection (i.e. List, ArrayList, and, Array) in a sequential manner.

We use iterators quite frequently in our daily life. For example remote control of the TV. Any remote control that we use, just pick up the TV remote control and start pressing Up and Down or Forward and Back keys to iterate through the channels.

Example to understand the Iterator Design Pattern in C#:

Suppose we have a collection of employees. Then we can easily iterate through the collection using either for or for each loop as shown below.

Understanding Iterator Design Pattern in C#

Here, the for-each loop sequentially accessing the elements from the collection without exposing the internal logic. Again if you want to use a different data structure then you need to change the client code. Is not it nice to provide a uniform interface for traversing different collections?

For example, you may have different types of collections in your application such as List, Array, ArrayList, Generic Dictionary, etc. For whichever types of collection you have, you will need to traverse or iterate through the items in the collections. The actual implementation of how to traverse different types of collections will be different, yet the client code should not be concerned about the details of the implementations. The Iterator Design Pattern helps you to hide such details and provide a generic interface for the client to traverse different types of collections as shown in the below image.

Understanding the Iterator Design Pattern in C#

Let us see the step by step procedure to achieve the above using the iterator design pattern.

Step1: Create the collection item

Here we are going to use the following Employee class as the item of our collection. So, create a class file with the name Employee.cs and then copy and paste the following code in it.

namespace IteratorDesignPattern
{
    class Elempoyee
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public Elempoyee(string name, int id)
        {
            Name = name;
            ID = id;
        }
    }
}

The above class is very straight forward. We have two properties and a constructor to initialize the properties.

Step2: Creating Abstract Iterator

Create a class file with the name AbstractIterator.cs and then copy and paste the following code in it. This class defines an interface for accessing and traversing elements.

namespace IteratorDesignPattern
{
    interface AbstractIterator
    {
         Elempoyee First();
         Elempoyee Next();
         bool IsCompleted { get; }
    }
}

Here, we declare two methods and one property with only get accessor. This interface is needed to be implemented by the Concrete Iterator class.

Step3: Creating Concrete Iterator

Create a class file with the name Iterator.cs and then copy and paste the following code in it. This class implements the AbstractIterator interface as well as keeps track of the current position in the traversal of the elements.

namespace IteratorDesignPattern
{
    class Iterator : AbstractIterator
    {
        private ConcreteCollection collection;
        private int current = 0;
        private int step = 1;

        // Constructor
        public Iterator(ConcreteCollection collection)
        {
            this.collection = collection;
        }

        // Gets first item
        public Elempoyee First()
        {
            current = 0;
            return collection.GetEmployee(current);
        }

        // Gets next item
        public Elempoyee Next()
        {
            current += step;
            if (!IsCompleted)
            {
                return collection.GetEmployee(current);
            }
            else
            {
                return null;
            }
        }

        // Check whether iteration is complete
        public bool IsCompleted
        {
            get { return current >= collection.Count; }
        }
    }
} 

The First method is used to return the First element from the collection. The current property is used to hold the index position of the current element. The Next method is used to return the next element from the collection by adding step with the current value. The IsCompleted method is used to check whether the iteration is completed or not.

Step4: Creating Aggregate

Create a class file with the name AbstractCollection.cs and then copy and paste the following code in it. This class defines an interface for creating an Iterator object.

namespace IteratorDesignPattern
{
    interface AbstractCollection
    {
        Iterator CreateIterator();
    }
}

Here, we define one method which is going to be implemented by the ConcreteAggregate class to return the Iterator object.

Step5: Creating ConcreteAggregate 

Create a class file with the name ConcreteCollection.cs and then copy and paste the following code in it. This class implements the AbstractCollection interface to return an instance of the proper Concrete Iterator class i.e. an instance of the Iterator class.

using System.Collections.Generic;

namespace IteratorDesignPattern
{
    class ConcreteCollection : AbstractCollection
    {
        private List<Elempoyee> listEmployees = new List<Elempoyee>();

        //Create Iterator
        public Iterator CreateIterator()
        {
            return new Iterator(this);
        }

        // Gets item count
        public int Count
        {
            get { return listEmployees.Count; }
        }

        //Add items to the collection
        public void AddEmployee(Elempoyee employee)
        {
            listEmployees.Add(employee);
        }

        //Get item from collection
        public Elempoyee GetEmployee(int IndexPosition)
        {
            return listEmployees[IndexPosition];
        }
    }
}

In order to test whether everything is working as expected, please modify the Main method of your Program class as shown below.

using System;
namespace IteratorDesignPattern
{
    public class Program
    {
        static void Main()
        {
            // Build a collection
            ConcreteCollection collection = new ConcreteCollection();

            collection.AddEmployee(new Elempoyee("Anurag", 100));
            collection.AddEmployee(new Elempoyee("Pranaya", 101));
            collection.AddEmployee(new Elempoyee("Santosh", 102));
            collection.AddEmployee(new Elempoyee("Priyanka", 103));
            collection.AddEmployee(new Elempoyee("Abinash", 104));
            collection.AddEmployee(new Elempoyee("Preety", 105));
            
            // Create iterator
            Iterator iterator = collection.CreateIterator();

            //looping iterator      
            Console.WriteLine("Iterating over collection:");
            
            for (Elempoyee emp = iterator.First(); !iterator.IsCompleted; emp = iterator.Next())
            {
                Console.WriteLine($"ID : {emp.ID} & Name : {emp.Name}");
            }
            Console.Read();
        }
    }
}

Output:

Real-time example of Iterator Design Pattern

Why do we need to use the Iterator Design Pattern in C#?

The Iterator Design Pattern in C# allows us to Access the elements of a collection without exposing its internal data structure. That means it allows you to navigate through a different collection of data using a common interface without knowing about their underlying implementation.

In the next article, I am going to discuss the Observer Design Pattern in C# with some examples. Here, in this article, I try to explain the Iterator Design Pattern step by step with an example. I hope you understood the need and use of the Iterator Design Pattern in C#.

Leave a Reply

Your email address will not be published. Required fields are marked *