Почему в операторе switch требуется перерыв после возврата yield? - PullRequest
23 голосов
/ 01 марта 2010

Может кто-нибудь сказать мне, почему компилятор считает, что 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 ]

26 голосов
/ 01 марта 2010

Потому что возвращение yield - это синтаксический сахар для генератора итераторов, и вы фактически не выходите из метода. И C # не допускает провала в операторах switch (и, похоже, вы этого не хотите здесь).

17 голосов
/ 02 марта 2010

Почему в операторе switch требуется break после возврата yield?

Вопрос предполагает неверную предпосылку. Оператор останова не требуется после возврата доходности в операторе переключения. Например:

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

Здесь мы имеем возврат доходности в операторе switch, за которым не следует перерыв. Затем следует вызов M (), а затем оператор throw. Это совершенно законно.

Настоящее правило заключается в том, что конечная точка секции переключателя не должна быть достижимой .

Конечные точки break, continue, return, goto, return и throw недоступны, поскольку все эти операторы ветвятся в другое место и не возвращаются, так что токен кода, следующий непосредственно за ними, недоступен. Это, в отличие от, скажем, вызова метода, который ветвится в другое место и затем возвращается, или возврата дохода, который передает управление обратно вызывающей стороне; когда вызывающая сторона передает управление обратно в блок итератора, управление выбирает то место, где остановился возврат доходности, поэтому конечная точка возврата доходности достижима.

Если вас интересует эта тема, я рекомендую прочесть раздел 8.1 спецификации.

2 голосов
/ 01 марта 2010

«Нормальный» возврат имеет две функции:

  1. Отметьте возвращаемое значение функции.
  2. Передача управления вызывающей стороне.

Возврат поля означает только возвращаемое значение; это не влияет на поток управления. После оператора yield return выполнение программы продолжается на следующей строке, где в вашем образце необходим разрыв, как и в любом другом операторе переключения.

...