Praburaj
Praburaj

Reputation: 613

Working of IEnumerator in c#

static void Main()
{
    DaysOfTheWeek days = new DaysOfTheWeek();

    foreach (string day in days)
    {
        Console.Write(day + " ");
    }

    // Output: Sun Mon Tue Wed Thu Fri Sat  
    Console.ReadKey();
}

public class DaysOfTheWeek : IEnumerable
{
    private string[] days = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

    public IEnumerator GetEnumerator()
    {
        for (int index = 0; index < days.Length; index++)
        {
            // Yield each day of the week.  
            yield return days[index];
        }
    }
}

What happens in the foreach loop. Does it calls the GetEnumerator function, for every iteration or the foreach is replaced by the GetEnumerator function? Does the complexity goes to O(n2) in this case?

Upvotes: 1

Views: 446

Answers (3)

Janne Matikainen
Janne Matikainen

Reputation: 5121

No, the GetEnumerator will not be called for every iteration. If you compile your code in release configuration and check the IL code generated you will end up with code like this.

IEnumerator enumerator2 = days.GetEnumerator();
try
{
    while (enumerator2.MoveNext())
    {
        Console.Write((string)enumerator2.Current + " ");
    }
}
finally
{
    IDisposable disposable = enumerator2 as IDisposable;
    if (disposable != null)
    {
        disposable.Dispose();
    }
}

So basically you could write that same code yourself, foreach is just syntactic sugar to help you write less code.

Upvotes: 0

wkl
wkl

Reputation: 1894

There is a nice desription of yield return in this blog post:

https://www.kenneth-truyers.net/2016/05/12/yield-return-in-c/

Basically it says that

Each iteration of the foreach loop calls the iterator method. When the yield return statement is reached the value is returned, and the current location in code is retained. Execution is restarted from that location the next time that the iterator function is called.

As the location is retained for the next call, I think complexity should be O(n) rather than O(n2).

Upvotes: 2

Patrick Hofman
Patrick Hofman

Reputation: 156918

The yield return creates a state machine that basically returns a value and then waits until the calling party (your first foreach) requests the next item in the enumerator.

IEnumerable is just an interface that describes a way to iterate over a set of data, the IEnumerator in there is the interface that describes how to call the iterator.

Upvotes: 4

Related Questions