收益表对计划流程的影响

Pet*_*217 2 c# yield-return

我正在尝试理解在C#中使用yield关键字,因为我正在使用的队列建模包广泛使用它.

为了演示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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

代码的作用非常明显,它只是将2提升到一个使用ComputePower它返回的功率IEnumerable.在调试代码时,我看到yield语句返回控制到foreach循环,value变量用最新的权力结果即更新.2,4,8,16,32.

没有完全理解使用yield,我期望ComputePower被多次调用作为值迭代通过ComputePower,我会看到"Arguments to ComputePower are "等控制台写入发生5次.但实际发生的事情似乎是该ComputePower方法只被调用一次.我"Arguments to ComputePower.."每次运行只看到一次字符串.

有人可以解释为什么会这样吗?它与yield关键字有关吗?

Mar*_*ius 7

foreach将迭代从ComputePower返回的IEnumerable."Yield return"会自动创建IEnumerable的实现,因此您不必手动滚动它.如果你在"while"-loop中放置一个断点,你会看到每次迭代都会调用它

来自msdn:

您可以使用foreach语句或LINQ查询来使用迭代器方法.foreach循环的每次迭代都会调用迭代器方法.在迭代器方法中达到yield return语句时,将返回表达式,并保留代码中的当前位置.下次调用迭代器函数时,将从该位置重新开始执行.

  • 关键部分是"下次调用迭代器函数时从该位置重新执行". (4认同)