foreach statement

If you want to learn some interesting facts about the foreach statement, please bear with me.

As defined on MSDN, the foreach statement repeats a group of embedded statements for each element in an array or an object collection that implements the System.Collections.IEnumerable or System.Collections.Generic.IEnumerable<T> interface.

I could say that this is not 100% exact: the compiler requires only an instance of a type that has a public, instance method named GetEnumerator() that returns an object whose type has a public, instance method named MoveNext() (that returns bool) and a public, instance get property named Current. Basically, the foreach statement  does not require explicit or implicit implementation of IEnumerable and IEnumerator interfaces, it requires only the contract defined by those interfaces.

The following code compiles and executes correctly:

using System;

class Program
{
    static void Main(string[] args)
    {
        var myEnumerable = new MyEnumerable(2);

        foreach (var item in myEnumerable)
        {
            Console.WriteLine(item);
        }
    }
}

class MyEnumerable
{
    private readonly int _count;

    public MyEnumerable(int count)
    {
        _count = count;
    }

    public MyEnumerator GetEnumerator()
    {
        return new MyEnumerator(_count);
    }
}

class MyEnumerator
{
    private readonly int _count;
    private int _state;

    public MyEnumerator(int count)
    {
        _state = 0;
        _count = count;
    }

    public bool MoveNext()
    {
        return _state++ < _count;
    }

    public int Current
    {
        get
        {
            return _state;
        }
        set
        {
        }
    }
}

NOTE: I could have defined MyEnumerable and MyEnumerator as value types (using struct instead of class) without any problem.

The forach statement is just syntactic sugar and it gets translated by the compiler into a try-finally statement that contains a while statement. So:

foreach (var item in myEnumerable)
{
    Console.WriteLine(item);
}

gets translated by the compiler into this code:

{
    var enumerator = myEnumerable.GetEnumerator();
    try
    {
        while (enumerator.MoveNext())
        {
            Console.WriteLine(enumerator.Current);
        }
    }
    finally
    {
        if (enumerator is IDisposable)
        {
            ((IDisposable)enumerator).Dispose();
        }
    }
}

NOTE: the foreach tries to dispose of the enumerator object.

Advertisements

2 thoughts on “foreach statement

  1. Sudhanshu

    Hey buddy,
    Although your demo is correct, you are essentially creating types that look like IEnumerable and IEnumerator, so even though you do not implement those interface explicitly, your types honour the contract! However, you could say that foreach does not check if your type explicitly implements an IEnumerable or IEnumerable

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s