Yield statement's effect on program flow
我试图理解在C中使用yield关键字,因为我使用的队列建模包广泛使用了它。
为了演示yield的使用,我正在使用以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | using System; using System.Collections.Generic; public class YieldTest { static void Main() { foreach (int value in ComputePower(2, 5)) { Console.Write(value); Console.Write(""); } Console.WriteLine(); } /** * Returns an IEnumerable iterator of ints * suitable for use in a foreach statement */ public static IEnumerable<int> ComputePower(int number, int exponent) { Console.Write ("Arguments to ComputePower are number:" + number +" exponent:" + exponent +" "); int exponentNum = 0; int numberResult = 1; while (exponentNum < exponent) { numberResult *= number; exponentNum++; // yield: // a) returns back to the calling function (foreach), // b) updates iterator value (2,4,8,16,32 etc.) yield return numberResult; } } } |
很明显,代码做了什么,它只是使用
由于不完全理解
有人能解释为什么会这样吗?它与
foreach将迭代ComputePower返回的IEnumerable。"yield return"自动创建IEnumerable的实现,因此您不必手动滚动它。如果在"while"循环中放置一个断点,您将看到每次迭代都会调用它。
来自MSDN:
You consume an iterator method by using a foreach statement or LINQ query. Each iteration of the foreach loop calls the iterator method. When a yield return statement is reached in the iterator method, expression 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.
当您在状态机生成的
在实践中,看起来您的方法体在每次迭代中执行一次,并且在每次到达
如果在方法的while循环中放置一个断点,您将看到堆栈包含对编译器生成的类型的
在较高的层次上,您可以将
在较低的层次上,
yield运算符将强制编译器创建一个将实现逻辑的自定义类。更好的理解方法是将结果exe反编译并监视到其中。