Working of IEnumerator in c#

余生颓废 提交于 2019-12-24 07:16:12

问题


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?


回答1:


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).




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/41257165/working-of-ienumerator-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!