问题
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