Tyro’s C# - The Curious Case of IEnumerable – Part 1

Its been a Hard day’s night, as i am working with the IEnumerable<T> in C# 2.0 to find what it is actually doing, and to share those experiences am writing this.

In Short i could say that IEnumerable<T> is a way used to implement iterators (like the foreach statement) in C# to iterate over Generic Collections, There is also a non generic IEnumerable version that exists. IEnumerable<T> is a simple interface that exposes a method which returns a IEnumerator<T>. IEnumerator<T> is the one that actually iterate the collection<T> (collection of elements) for you under the woods and return an element of type T. These statements may be foxing, but the more you are focused you keep going. I will start from where i started to learn this i.e foreach.

Let’s take a simple example to illustrate this

class Duck
  {
      static void Main(string[] args)
      {
          int[] nos = new int[] { 12, 45, 17, 14, 21 };
          foreach (int item in nos)
          {
              Console.WriteLine(item);
          }
      }
  }

In the above code we are creating an int [] with some data and iterating through it using the foreach statement and display them. Did i hear a “SO WHAT” from you ! But wait buddy, then it smells that you left lot of things Unquestioned. Let me ask some.

  1. How does the foreach know whether the collection being used can be iterated?
  2. How do the foreach statement know the number of elements in the Array Collection?
  3. How do the foreach know the data type of the collection
  4. How does it learn to move to the next element.

Well, Interesting ah! Okie, lets walkthrough the answers.

1. How does the foreach know whether the collection being used can be iterated?

When the loop starts executing, the first thing the compiler will check is whether the collection or any object mentioned (In the previous example the object is nos) implements the GetEnumerator() method. Arrays in .NET, all collections (Generic and Non Generic) implicitly implemented the GetEnumerator() method from interface IEnumerable.

     public abstract class Array : ICloneable, IList, ICollection, IEnumerable
     public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable

2. How do the foreach statement know the number of elements in the Array Collection?

Each time an collection is iterated using a foreach loop, the GetEnumerator() method of the corrosponding collection class is called (In the previous example, the GetEnumerator() of the Array class is called for each iteration). The GetEnumerator somehow return an object at the next available position if it is available , else it returns no object. The foreach will terminate when it does not get an object.  So the answer is foreach never know the size of the collection. It depends on the GetEnumerator() for everything….

3. How do the foreach know the data type of the collection

The data type of the collection being iterated strongly typed in case of IEnumerable<T> and if the user initializes T with a suitable type that would be the type in the foreach loop. If the user implemented the IEnumerable interface, then all the items iterated in any collection will be of type System.object. Classical example for this is  the the ArrayList class in .NET 1.1. which will return objects of type System.Object when we iterate through the list, which is not the case with 2.0. Generics Rocks !!

4. How does it learn to move to the next element.

We had been talking a lot on the GetEnumerator() method. The answer to this question is no exception. The foreach loop again depends on the GetEnumerator() function to move to the next element in the collection (somewhat synonymous to the answer to the 2nd Question). It takes care of maintaining an index to the underlying collection being iterated.

We will see the implementation of the odd man GetEnumerator() in the next blog.

soundararajan