为什么IEnumerator必须至少有一个yield语句,即使它不可达?

时间:2017-02-14 21:48:41

标签: c# yield ienumerator

为什么这段代码:

public IEnumerator Test()
{
}

给你一个错误:

  

错误CS0161' Test.GetEnumerator()':并非所有代码路径都返回值

但是这段代码:

public IEnumerator Test()
{
    if(false)
        yield return 0;
}

隐而不宣'吨? (并按预期工作;第一个MoveNext()返回false)

当使用IEnumerators作为协同程序时,有时你想制作一个没有异步操作的协同程序(IEnumerator)(不会产生任何东西)但是将来可能会这样做。

2 个答案:

答案 0 :(得分:3)

来自C#规范:

  

调用包含一个或多个yield语句(第8.14节)的块   迭代器块。迭代器块用于实现功能   成员作为迭代器(§10.14)。

因此,如果你有一个或多个yield语句,无论是否可达,你的方法都是迭代器(在生成迭代器类的引擎盖下)。但是,如果您没有任何yield语句,则您的方法是序数方法(不是迭代器),其返回值为IEnumerable类型。与任何其他返回某些值的方法一样,您必须返回所需类型的值或从方法体中抛出异常。当您拥有返回stringint值的方法时,将应用相同的规则。

答案 1 :(得分:0)

如果方法块中根本没有yield个语句,那么它不是迭代器块,并且编译器不知道你想要执行相关的转换它。它将像处理返回值的任何其他方法一样对待它。

编译器团队可以完成他们对async所做的操作,并在方法的签名中添加了一个新关键字,如果存在,则使该方法成为迭代器块,允许身体中的yield陈述,并允许空身被视为什么都没有,但他们选择不这样做。

如果方法体中某处有yield语句,实际上并不需要可靠地命中一个方法来正确编译和运行。在迭代器块中,命中方法的结尾意味着序列结束,即使尚未产生任何项目,这是完全合理的行为。该方法仍有IEnumerableIEnumerator返回,它只是没有值可以产生。