【问题标题】:Why does an IEnumerator have to have at least one yield statement, even if it's unreachable?为什么 IEnumerator 必须至少有一个 yield 语句,即使它无法访问?
【发布时间】:2017-07-03 09:01:41
【问题描述】:

为什么会有这段代码:

public IEnumerator Test()
{
}

给你一个错误:

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

但是这段代码:

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

不是吗? (并且按预期工作;第一个 MoveNext() 返回 false)

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

【问题讨论】:

  • 你也可以使用yield break;来代替一个假的if语句。

标签: c# yield ienumerator


【解决方案1】:

来自 C# 规范:

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

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

【讨论】:

    【解决方案2】:

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

    编译器团队可以完成他们对 async 所做的事情,并在方法的签名中添加了一个新关键字,如果存在,则使该方法成为迭代器块,允许 @987654323 @ 语句,并允许将空的主体视为不产生任何内容,但他们选择不这样做。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-06
      • 2023-03-03
      • 2014-01-07
      • 2014-01-12
      • 2022-08-21
      • 1970-01-01
      • 2014-01-09
      • 2013-02-05
      相关资源
      最近更新 更多