Зачем мне нужен перерыв?

Мне было интересно, почему С# требует, чтобы я использовал break в инструкции switch, хотя оспаривание семантики по определению не допускается. следовательно, компилятор мог бы сгенерировать break в конце каждого case -блока и избавить меня от хлопот.

Однако есть один сценарий (который уже обсуждался на этом сайте), который я мог бы придумать, что может быть причиной явного использования break:

switch (foo) {
    case 0:
    case 1:
        bar();
        break;
    default:
        break;
}

Здесь метод bar() вызывается, если foo имеет либо значение 0, либо 1.

Этот параметр нарушит истинное значение слова, если компилятор будет генерировать операторы break сам по себе. Это и есть ли причина, почему перерыв является обязательным или существуют другие веские причины?

Ответы

Ответ 1

Я подозреваю, что причина, по которой С# требует, чтобы разработчик размещал оператор break или терминала в конце каждого случая для ясности.

Это позволяет избежать появления новичков на языке, предполагая, что switch() в С# ведет себя как переключатель на C или С++, где происходит падение поведения. Только в случаях смежных пустых случаев проваливается через С#, что относительно очевидно.

EDIT: На самом деле, в С# провал всегда является незаконным. Однако в законодательстве есть один случай, связанный с двумя или более ярлыками. Эрик Липперт подробно описывает об этом поведение и то, как он отличается от операторов switch C/С++.

Вам может быть интересно прочитать эту статью в блоге Эрика Липлетса.

Ответ 2

Вопрос предполагает ложность и поэтому не может быть дан ответ. Язык не требует перерыва в конце раздела переключателя. Язык требует, чтобы в списке инструкций секции переключателя была недостижимая конечная точка. "break" - это наиболее часто используемый оператор, обладающий этим свойством. Совершенно законно заканчивать секцию переключения "return", "goto case 2;", "throw new Exception()"; или "while (true) {}" (или в некоторых случаях продолжать, хотя обычно это плохая идея.)

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

Если ваш вопрос лучше сформулирован как "почему компилятор автоматически не исправил мою ошибку, когда мне не удалось создать раздел переключения с списком операторов с недостижимой конечной точкой, вставив оператор от моего имени?", то ответ заключается в том, что С# не "задумывается о том, что разработчик, вероятно, имел в виду и путался", из-за своего рода языка. Некоторые языки - JScript, например, но С# - нет.

Мы считаем, что программисты на С#, которые совершают ошибки, хотят, чтобы их рассказывали об этих ошибках, чтобы они могли преднамеренно и намеренно их исправить, и что это хорошо. Наши клиенты говорят нам, что они не хотят, чтобы компилятор задумывался о том, что они имели в виду, и надеется на лучшее. Вот почему С# также не делает предположений о том, где вы хотели поставить эту пропавшую точку с запятой, как это делает JScript, или тихо проваливается, когда вы пытаетесь изменить переменную только для чтения, как это делает JScript и т.д.

Ответ 3

Предоставляя возможность прерывания, вы открываете себя таким образом:

switch (thing_result)
{
    case GOOD_THING:
        IssueReward();
        // UH-OH, missing break!
    case BAD_THING:
        IssuePunishment();
        break;
}

Разработчики языка С# пытались помочь программистам избежать ошибок на языках, которые были перед ним, в основном, заставляя программиста быть более явным (например, явное использование ключевого слова "переопределить" или "новое" для реализации или затенения виртуальных участников).

Ответ 4

Мое понимание вопроса заключается в том, что оно было включено в синтаксис Си ++.

Ответ 5

Если вам не нужно добавлять разрыв, возникает проблема

switch (number)
{
    case 0:
    case 1:
        DoSomething();
}

Что произойдет, если number == 0? Это пустой случай, который ничего не делает или выполнит DoSomething()?