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(params)为字段,而“Test1”未被调用。
“Test2”的工作原理是“设计”:)
最近怎么回事?
答案 0 :(得分:15)
Test1
被调用,但除非您遍历结果,否则不会在yield break
上找到断点。
基本上Test1
被转换为一个为你实现IEnumerable
的状态机......但你方法的所有主体都在那个状态机内,除非你使用状态机通过调用GetEnumerator()
然后MoveNext()
(或使用foreach
循环),您将看不到您的身体执行。
有关详情,请参阅我的general iterator article和我的iterator implementation文章,以及Eric Lippert的两篇博文:Psychic Debugging part one和Psychic Debugging part two。
答案 1 :(得分:1)
由于您提到了Python,我将指出Python中的生成器与C#中的生成器非常相似。只有yield break
单独将C#方法转换为生成器的微小差别,而raise StopIteration
的Python等价物则不会。
>>> 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