c# - yield语句对程序流程的影响

标签 c# yield-return

我试图了解 yield 关键字在 C# 中的用法,因为我正在使用的队列建模包广泛使用了它。

为了演示 yield 的使用,我正在使用以下代码:

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 + "\n");
        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;
        }
    }
}

代码的作用非常明显,它只是使用返回 IEnumerableComputePower 将 2 提高到一个幂。在调试代码时,我看到 yield 语句将控制权返回给 foreach 循环,并且 value 变量更新为电源即。 2、4、8、16、32。

不完全理解 yield 的用法,我预计 ComputePower 会在值遍历 ComputePower 时被调用多次,而且我会看到 "Arguments to ComputePower are " 等控制台写入发生 5 次。但实际上发生的是 ComputePower 方法似乎只被调用一次。我每次运行只看到一次 "Arguments to ComputePower.." 字符串。

有人能解释一下为什么会这样吗?它与 yield 关键字有关吗?

最佳答案

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.

关于c# - yield语句对程序流程的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16806420/

相关文章:

c# - Rhino Mock 执行 yield return

c# - IEnumerator 或 IEnumerable 中的“产量”?

c# - 更改不会永久保存到 SQL Server Compact 版本中

c# - Selenium webdriver 窗口处理 c# switchTo 失败

c# - 在 C# 中使用图片代替矩形

c# - FakeItEasy 重置对对象的调用

c# - 关于 Command Line Compiler 和 MSBuild 的一些困惑

c# - C#中 "yield"关键字有什么用?

c# - 返回 IEnumerable 时是否有理由不使用 'yield return'?

c# - 在 TPL 数据流中使用 async/await 和 yield return