CSharp - Enumerator and Enumerable

What is Enumerator

An enumerator is a read-only, forward-only cursor over a sequence of values.

An enumerator is an object that implements either of the following interfaces:

System.Collections.IEnumerator
System.Collections.Generic.IEnumerator<T>

Enumerable

The foreach statement iterates over an enumerable object.

An enumerable object either:

  • Implements IEnumerable or IEnumerable<T>
  • Has a method named GetEnumerator that returns an enumerator

IEnumerator and IEnumerable are defined in System.Collections.

IEnumerator<T> and IEnumerable<T> are defined in System.Collections.Generic.

The enumeration pattern is as follows:

class Enumerator implements IEnumerator or IEnumerator<T>
{
       public IteratorVariableType Current { get {...} }
       public bool MoveNext() {...}
}

class Enumerable implements IEnumerable or IEnumerable<T>
{
       public Enumerator GetEnumerator() {...}
}

IEnumerator interface defines the protocol by which elements in a collection are traversed in a forward-only manner.

Its declaration is as follows:

public interface IEnumerator
{
       bool MoveNext();
       object Current { get; }
       void Reset();
}

MoveNext advances the current cursor to the next position, returning false if there are no more elements in the collection.

Current returns the element at the current position.

MoveNext must be called before retrieving the first element.

Reset method if implemented moves back to the start, allowing the collection to be enumerated again.

Collections may provide enumerators, via the interface IEnumerable:

public interface IEnumerable
{
       IEnumerator GetEnumerator();
}

The following example illustrates low-level use of IEnumerable and IEnumerator:

string s = "Hello";

// Because string implements IEnumerable, we can call GetEnumerator():
IEnumerator rator = s.GetEnumerator();

while (rator.MoveNext())
{
       char c = (char) rator.Current;
       Console.Write (c + ".");
}

C# provides a shortcut: the foreach statement.

The following code does the same as the code above using foreach:

Demo

using System;
class MainClass// w w  w  . ja v  a 2 s. c om
{
   public static void Main(string[] args)
   {
     string s = "Hello";      // The String class implements IEnumerable

     foreach (char c in s)
        Console.Write (c + ".");
   }
}

Result

IEnumerable<T> and IEnumerator<T>

IEnumerator and IEnumerable are always implemented in conjunction with their extended generic versions:

public interface IEnumerator<T> : IEnumerator, IDisposable
{
       T Current { get; }
}

public interface IEnumerable<T> : IEnumerable
{
       IEnumerator<T> GetEnumerator();
}

Related Topics