Eliminate Unnecessary Code and Boost Performance with C# 2.0 Iterators

A design pattern is a solution that focuses on solving a particular problem or issue that commonly occurs. Design patterns are often associated with object-oriented programming, but they are not exclusive to it. Non-computing disciplines also have concepts similar to the design pattern, which is likely from where programmers borrowed the concept.

The existence of a design pattern does not imply that only one solution to the problem exists, nor does it mean it is the best solution in all cases. Patterns merely provide a best-practice approach to a particular problem as learned through the countless experiences of the programming community. There are often several variations of a pattern for a particular problem. It is up to each programmer to determine if and when to apply a particular pattern. Often, the programming environment in use can influence the choice of which pattern to apply. Not all programming environments and languages support all design patterns. What may be easy to create in one environment or language may be extremely difficult in another. (Find more examples of design patterns in the article titled Implement Common Creational Design Patterns”.)

The idea behind the iterator design pattern is to expose a controlled manner to sequentially access the elements of an aggregate object without exposing its internal representation or design. Actions such as First(), Next(), CurrentItem(), and IsDone() are commonly exposed operations. Many of the System.Collection namespace classes implement the iterator pattern. Although they may use different names for the operations, they’re basically the same. They expose a GetEnumerator() method, which returns the concrete iterator for the particular class. The iterator is used to traverse the structure.

Iterator Implementation Sample Code

The following sample code demonstrates an implementation of the iterator design pattern in the 1.0 and 1.1 versions of the Microsoft .NET Framework. It implements the IEnumerable interface in an outer class, which mandates the GetEnumerator method be implemented. This allows you to use it in foreach loops:

using System;
using System.Collections;

namespace CodeGuru.IteratorsSample
{
   class IteratorTest : IEnumerable
   {
      private ArrayList items = new ArrayList();

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

      public object this[int index]
      {
         get { return items[index]; }
         set { items.Insert(index, value); }
      }

      public IEnumerator GetEnumerator()
      {
         return new IteratorSampleEnumerator(this);
      }

      private class IteratorSampleEnumerator : IEnumerator
      {
         IteratorTest aggregate = null;
         int index = -1;

         public IteratorSampleEnumerator(IteratorTest aggregate)
         {
            this.aggregate = aggregate;
         }

         public virtual object Current
         {
            get { return this.aggregate[index]; }
         }

         public virtual bool MoveNext()
         {
            index++;
            if (index >= this.aggregate.Count)
            {
               return false;
            }
            else
            {
               return true;
            }
         }

         public virtual void Reset()
         {
            index = -1;
         }
      }
   }

   class Program
   {
      static void Main(string[] args)
      {
         // Create an iterator and add sample data
         IteratorTest tests = new IteratorTest();
         tests[0] = "Test 1";
         tests[1] = "Test 2";
         tests[2] = "Test 3";
         tests[3] = "Test 4";
         tests[4] = "Test 5";

         foreach (object test in tests)
         {
            Console.WriteLine(test);
         }

         // Wait for the user so we can see output
         Console.ReadLine();
      }
   }
}

The sample output from the application will look something like this:

Test 1
Test 2
Test 3
Test 4
Test 5

To return an IEnumerator instance, you need another class that has intimate knowledge of your class and can iterate through the internal aggregate implementation.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read