6
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace ConsoleApplication4
{
    class Program
    {
        static void Main (string[] args)
        {
            var test1 = Test1(1, 2);
            var test2 = Test2(3, 4);
        }

        static IEnumerable Test1(int v1, int v2)
        {
            yield break;
        }

        static IEnumerable Test2 (int v1, int v2)
        {
            return new String[] { };
        }
    }
}

“test1”似乎是一个 IEnumerable,其中 v1 和 v2(参数)作为字段,并且没有调用“Test1”。

“Test2”工作“设计”:)

这是怎么回事?

4

2 回答 2

15

Test1 调用,但除非你遍历结果,否则你不会在yield break.

基本上Test1被转换成一个IEnumerable为你实现的状态机......但是你的方法的所有主体都在那个状态机内,除非你通过调用然后(或使用循环)来使用状态机,否则你不会看到你的身体执行。GetEnumerator()MoveNext()foreach

有关更多信息,请参阅我的通用迭代器文章迭代器实现文章,以及 Eric Lippert 的两篇博文:心理调试第一部分心理调试第二部分

于 2009-09-24T13:28:55.333 回答
1

既然您提到了 Python,我将指出 Python 中的生成器的工作方式与 C# 中的生成器非常相似。只有一个小区别可以yield break单独将 C# 方法转换为生成器,而 Python 等价物raise StopIteration不会。

>>> def f():
...     print "Beginning of generator"
...     if False: yield
...     print "End of generator"
... 
>>> it = f()
>>> it
<generator object at 0x94fae2c>
>>> it.next()
Beginning of generator
End of generator
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
于 2009-09-24T14:03:05.793 回答