Можно / нужно ли выкидывать исключения в операторе c # switch? - PullRequest
9 голосов
/ 22 апреля 2010

У меня есть запрос вставки, который возвращает int. Исходя из этого, я могу захотеть сделать исключение. Это уместно делать в операторе switch?

 switch (result)
        {

            case D_USER_NOT_FOUND:
                throw new ClientException(string.Format("D User Name: {0} , was not found.", dTbx.Text));
            case C_USER_NOT_FOUND:
                throw new ClientException(string.Format("C User Name: {0} , was not found.", cTbx.Text));
            case D_USER_ALREADY_MAPPED:
                throw new ClientException(string.Format("D User Name: {0} , is already mapped.", dTbx.Text));
            case C_USER_ALREADY_MAPPED:
                throw new ClientException(string.Format("C User Name: {0} , is already mapped.", cTbx.Text));
            default:

                break;
        }

Обычно я добавляю операторы break к коммутаторам, но они не будут включены. Это плохой дизайн? Пожалуйста, поделитесь со мной своими мнениями / предложениями.

Спасибо, ~ ck в Сан-Диего

Ответы [ 8 ]

12 голосов
/ 22 апреля 2010

Почему бы и нет?

Из Язык программирования C #, третье издание. Автор Андерс Хейлсберг и др., Стр. 362:

Список операторов секции switch обычно заканчивается оператором break, goto case или goto default, но любая конструкция, которая делает конечную точку списка операторов недостижимой, разрешена. [...] Аналогично, оператор throw или return всегда передает управление в другом месте и никогда не достигает своей конечной точки. Таким образом, следующий пример действителен:

switch(i) {
case 0:
    while(true) F();
case 1:
    throw new ArgumentException();
case 2:
    return;
}
4 голосов
/ 22 апреля 2010

Нет проблем ... почему это плохой дизайн?

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

static private Dictionary<int, string> errorMessages;
static
{
    // create and fill the Dictionary
}

// meanwhile, elsewhere in the code...
if (result is not ok) {
    throw new ClientException(string.Format(errorMessages[result], cTbx.Text, dTbx.Text));
}

В самих сообщениях вы можете выбрать соответствующий параметр с помощью {0}, {1} и т. Д.

3 голосов
/ 22 апреля 2010

Я не совсем согласен с вашими соглашениями об именах переменных;), но я не понимаю, почему то, что вы сделали, было бы неуместно. Это выглядит как довольно элегантный способ перевода ошибки с одного носителя на другой.

Я предполагаю, что ваш "запрос вставки" является некоторой формой хранимого процесса.

1 голос
/ 22 апреля 2010

Если возможно, было бы лучше, если бы вы бросали, где бы ни был установлен неудавшийся результат, в противном случае вам придется выполнять как проверку результата, так и бросок. Но, конечно, это невозможно.

Кроме того, я бы превратил ваши строки ошибок в ресурсы или константы с заполнителями, чтобы вам не приходилось менять несколько мест, если вы хотите изменить формулировку.

0 голосов
/ 22 апреля 2010

Может быть, я умоляю отличаться от всех ответов здесь ..

Вместо того, чтобы переключать код, я бы предпочел передать result классу ClientException и позволить ему решить, чтоСтрока, которую он должен показать, а не иметь уродливый переключатель повсюду для создания различных сообщений

Мой код будет выглядеть так:

throw new ClientException(result, cTbx.Text);

Так что, даже если вы можете выдавать ошибки в switch...case, вы можете избежать всего этого - мой взятие

0 голосов
/ 22 апреля 2010

Я не вижу проблем с использованием переключателя в вашем случае.

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

0 голосов
/ 22 апреля 2010

В вашем подходе нет ничего плохого. Операторы Switch намного легче читать, чем операторы if / then (и, возможно, быстрее). Другая вещь, которую вы могли бы сделать, это загрузить возможные исключения в

Dictionary<Result_Type, Exception>

и вытяните исключение оттуда. Если у вас много операторов switch, это сделает код более компактным (и вы можете добавлять и удалять их во время выполнения, если вам нужно).

0 голосов
/ 22 апреля 2010

Я думаю, что это нормально. Похоже, вы отображаете код возврата в исключение, используя оператор switch. Пока не так много случаев, это не проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...