执行收益率返回后的代码

hel*_*elb 10 c# yield-return

请考虑以下示例:

class YieldTest
{
    static void Main(string[] args)
    {
        var res = Create(new string[] { "1 12 123", "1234", "12345" });
    }

    static IEnumerable<int> Create(IEnumerable<string> strings)
    {
        foreach(string s in strings)
        {
            yield return s.Length;
            if(s.Contains(' '))
            {
                string[] tokens = s.Split(' ');
                foreach(string t in tokens)
                {
                    yield return t.Length;
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Create回复{8,1,2,3,4,5} 的召唤.

让我困惑的是执行yield return语句后的代码.(他们为什么要命名yield return而不只是yield?)文档告诉我们

在迭代器方法中达到yield return语句时,将返回表达式,并保留代码中的当前位置.

那是什么意思?返回何处发生?什么是迭代器方法?

dca*_*tro 11

这意味着编译器将您的代码转换为状态机.

当你打电话给Create方法时,你会得到一个IEnumerable<T>.然后你可以打电话GetEnumerator()给它并获得一个IEnumerator<T>.

现在,每次通话时间MoveNext在这个迭代器,你的代码将执行,直到它找到的第一个yield声明(无论是yield returnyield break).

如果它命中a yield return x,则MoveNext返回true并且迭代器的Current属性将被设置为x,并且下次调用时将执行其余代码MoveNext.

这种情况发生,直到没有更多的代码要运行或代码命中yield break.那时,MoveNext将返回false.

yield return 1;
yield return 2;
yield return 3;
Run Code Online (Sandbox Code Playgroud)

调用MoveNext这段代码将在前三次返回true,并且在每次迭代时,Current将设置为1,2和3.

编辑2:

关于yield return ??语法,来自Eric Lippert的Ambiguous Optional Parentheses,第三部分

当他们设计C#2.0时他们遇到了这个问题:

yield(x);

这是否意味着"在迭代器中产生x"或"使用参数x调用yield方法?" 通过将其更改为

yield return(x);

它现在是毫不含糊的; 它不可能意味着"称之为收益率方法".