Blog / Design Patterns
The Iterator Design Pattern in C# and .Net
  • Dec 29, 2020
  • 80
  • 65

The Iterator Design Pattern is the third pattern in the Behavioral Category that I would like to talk about. Let's take a look at how and when to implement this pattern in C# and .Net.

Note: Code can be downloaded at my Github.


Advertisement
 


1. What is the Iterator Design Pattern?

Iterator is a behavioral design pattern that lets you traverse elements of a collection without exposing its underlying representation (list, stack, tree, etc.). The iterator pattern decouples algorithms from containers; in some cases, algorithms are necessarily container-specific and thus cannot be decoupled.

The iterator pattern is a design pattern in which an iterator is used to traverse a container and access the container's elements.

2. When to implement the Iterator Design Pattern?

The Iterator Design Pattern is used when:

  • Your collection has a complex data structure under the hood, but you want to hide its complexity from clients (either for convenience or security reasons).
  • You want to reduce duplication of the traversal code across your app.
  • You want your code to be able to traverse different data structures or when types of these structures are unknown beforehand.

3. How to implement the Iterator Design Pattern?

Below are steps to implement the Iterator Design Pattern.

Step 1: Create an Iterator abstract class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
abstract class Iterator : IEnumerator
{
    object IEnumerator.Current => Current();
 
    // Returns the key of the current element
    public abstract int Key();
 
    // Returns the current element
    public abstract object Current();
 
    // Move forward to next element
    public abstract bool MoveNext();
 
    // Rewinds the Iterator to the first element
    public abstract void Reset();
}
 
abstract class IteratorAggregate : IEnumerable
{
    // Returns an Iterator or another IteratorAggregate for the implementing
    // object.
    public abstract IEnumerator GetEnumerator();
}

Step 2: Create an Ordering class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
class AlphabeticalOrderIterator : Iterator
{
    private WordsCollection _collection;
 
    // Stores the current traversal position. An iterator may have a lot of
    // other fields for storing iteration state, especially when it is
    // supposed to work with a particular kind of collection.
    private int _position = -1;
 
    private bool _reverse = false;
 
    public AlphabeticalOrderIterator(WordsCollection collection, bool reverse = false)
    {
        this._collection = collection;
        this._reverse = reverse;
 
        if (reverse)
        {
            this._position = collection.getItems().Count;
        }
    }
 
    public override object Current()
    {
        return this._collection.getItems()[_position];
    }
 
    public override int Key()
    {
        return this._position;
    }
 
    public override bool MoveNext()
    {
        int updatedPosition = this._position + (this._reverse ? -1 : 1);
 
        if (updatedPosition >= 0 && updatedPosition < this._collection.getItems().Count)
        {
            this._position = updatedPosition;
            return true;
        }
        else
        {
            return false;
        }
    }
 
    public override void Reset()
    {
        this._position = this._reverse ? this._collection.getItems().Count - 1 : 0;
    }
}
 
// Concrete Collections provide one or several methods for retrieving fresh
// iterator instances, compatible with the collection class.
class WordsCollection : IteratorAggregate
{
    List<string> _collection = new List<string>();
 
    bool _direction = false;
 
    public void ReverseDirection()
    {
        _direction = !_direction;
    }
 
    public List<string> getItems()
    {
        return _collection;
    }
 
    public void AddItem(string item)
    {
        this._collection.Add(item);
    }
 
    public override IEnumerator GetEnumerator()
    {
        return new AlphabeticalOrderIterator(this, _direction);
    }
}

Done! So now you can execute the code on the client:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Program
{
    static void Main(string[] args)
    {
        // The client code may or may not know about the Concrete Iterator
        // or Collection classes, depending on the level of indirection you
        // want to keep in your program.
        var collection = new WordsCollection();
        collection.AddItem("First");
        collection.AddItem("Second");
        collection.AddItem("Third");
 
        Console.WriteLine("Straight traversal:");
 
        foreach (var element in collection)
        {
            Console.WriteLine(element);
        }
 
        Console.WriteLine("\nReverse traversal:");
 
        collection.ReverseDirection();
 
        foreach (var element in collection)
        {
            Console.WriteLine(element);
        }
    }
}

Output:


4. Conclusion

The Iterator Design Pattern is needed when you expect to have a complicated collection and have to process the list by looping through it. I hope this tutorial is helpful. Please let me know your thoughts in the comment section below.


If you have a Website or a Web API developed by using .Net Core and looking for a way to publish your applications, this post will explain how to do it using GoDaddy Windows Hosting.Note: at this mome ...

Search text in Stored Procedure in SQL SELECT DISTINCT o.name AS Object_Name, o.type_desc FROM sys.sql_modules m INNER JOIN sys.objects o ON m.object_id = o ...

Using cherry-pick to select specific commits for your Pull Request.1. Create a new branch based on the target of the Pull Requestgit branch cherry-branch origin/master2. Switch to a new branchgit chec ...

After deployment Angular and API on IIS, it's working fine unless I refresh the page. Once refreshed, the web encountered 404 error. In this article, I will explain how to resolve this.Since Angular i ...

There are some benefits of keeping both UI and API parts in the same place for small projects. In this article, I will explain how I did to deploy Angular Web and ASP .Net Core API in the same folder ...

I got CORS error after publishing my API and Angular app to IIS even though CORS is enabled and the origins of the Angular app is added. Below is how I resolved this issue.Just simple, make sure you s ...

1. The Situation:Error Message:&nbsp;Pulse Secure Application failed to load Java. Please install correct JRE version.Description: This issue happens when I'm using a M1 Mac with a correct version of ...

Accelerated Mobile Pages (AMP)&nbsp;focuses on delivering static content from publishers as quickly as possible and possibly rewards early adopters with a boost in rank. Let's see how to implement it ...

Below is how to decrypt/convert a Hex string value into text using VB.Net:Decrypting Hex string value to string in VB.Net Function HexToString(ByVal hex As String) As String Dim text As New Sy ...