Share via


Design pattern in .NET: iterator

The iterator pattern plays very important role in STL. In STL, iterators are the glue between algorithms and containers. STL algorithms and containers are independent of each other; each STL container implements its own iterator and the STL algorithms use iterators to access the elements of the containers. For example, there is a for_each algorithm in STL that uses iterators to access each element of a container:

void PrintNumber(int number)

{

        cout << number << endl;

}

 

int _tmain(int argc, _TCHAR* argv[]) 

{

        int numbers[] = {1,2,3,4,5};

 

        vector<int> vi(numbers, numbers+5);

 

        //vi.begin() and vi.end() return two iterators:

        for_each(vi.begin(),vi.end(),PrintNumber);

}

 

In .NET, you implement the iterator pattern using the IEnumerable and IEnumerator interfaces and their generic version IEnumerable<T> and IEnumerator<T>. IEnumerable returns an IEnumerator object and the IEnumerator objects implement the actual "iterator" code. You can use tools such as Reflector to check the classes such as List<T>, Dictionary<TKey, TValue> in .NET framework library to see how these classes implement the IEnumerable/ Ienumerable<T> interfaces. .NET language such as C# has more integral support for the iterator pattern, if a class implements the IEnumerale interface, you can use the foreach statement to access each element of the classes.

 

The yield return statement makes it even easier to implement the iterator pattern. For example, if you use yield return statement in below class, the compiler will generate code for you and the compiler generated code implements the IEnumerable interface and then you can use the class in the foreach statement, you can use reflector to check the compiler generated code to see how the IEnumerable interface is implemented:

 

public class DaysOfTheWeek

{

    string[] m_Days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" };

 

    public IEnumerable Days()

    {

        for (int i = 0; i < m_Days.Length; i++)

        {

            yield return m_Days[i];

        }

    }

}

 

DaysOfTheWeek obj = new DaysOfTheWeek();

foreach(string day in obj.Days())

{

        Console.WriteLine(day);

}