为什么在switch语句中返回yield后需要中断?

时间:2010-03-01 19:46:27

标签: c# switch-statement break yield-return

有人可以告诉我为什么编译器在以下代码中认为break之后需要yield return

foreach (DesignerNode node in nodeProvider.GetNodes(span, node => node.NodeType != NDjango.Interfaces.NodeType.ParsingContext))
{
    switch (node.ErrorMessage.Severity)
    {
        case -1:
        case 0:
            continue;
        case 1:
            yield return new TagSpan<ErrorTag>(node.SnapshotSpan, new ErrorTag(PredefinedErrorTypeNames.Warning));
            break;
        default:
            yield return new TagSpan<ErrorTag>(node.SnapshotSpan, new ErrorTag(PredefinedErrorTypeNames.SyntaxError));
            break;
    }
}

3 个答案:

答案 0 :(得分:26)

因为yield return只是迭代器生成器的语法糖,并且您实际上并没有退出任何方法。并且C#不允许在switch语句中使用(并且它看起来不像你想要的那样)。

答案 1 :(得分:17)

  

为什么在switch语句中返回yield后需要break?

这个问题假设一个不正确的前提。在switch语句中返回yield后,break语句不需要 。例如:

switch(x)
{
case 123:
    yield return 456;
    M();
    throw new Exception();
case 789: // and so on

这里我们在switch语句中有一个yield return,后面没有中断。接下来是对M()的调用,然后是一个throw语句。这完全合法。

真正的规则是交换机部分的终点必须无法访问

无法访问break,continue,return,goto,return和throw的结束点,因为所有这些语句都分支到另一个位置并且不会返回,因此无法访问紧跟在它们后面的代码令牌。这与例如方法调用形成对比,方法调用分支到另一个位置然后返回,或者收益返回,它将控制权转移回调用者;当调用者将控制权转移回迭代器块时,控制权将从收益率返回的位置开始,因此可以获得收益率返回的终点。

如果您对此主题感兴趣,我建议您阅读规范的第8.1节。

答案 2 :(得分:2)

“正常”返回有两个功能:

  1. 标记函数的返回值。
  2. 将控制权转移给来电者。

返回标记仅返回值;它不会影响控制流程。在yield return语句之后,程序在下一行继续执行,样本中需要中断,就像在任何其他switch-case语句中一样。

相关问题