#c_sharp #исключения #try_catch
Я сейчас изучаю C# по учебнику Шилдта, а он учит заключать все узкие моменты в try-catch. Это нормальная практика ветвления кода, или лучше пользоваться if-else? Я, конечно, понимаю разницу между ошибками и исключениями. Но теперь у меня расплывается граница между некоторыми исключениями и обычными ветвлениями в коде. Например операция деления одного числа на другое подразумевает, что пользователь может (попробовать) поделить число на ноль. С одной стороны результат этой операции будет исключением, которое можно обработать. С другой стороны можно и не доводить дело до исключения, заранее проверяя вводимые числа. Как принято поступать в обществе профессиональных программистов?
Ответы
Ответ 1
Вообще подмена исключений условными блоками - не самая здравая идея. Любая функция (метод) в принципе должна выполнять одну возложенную на нее задачу. Если по тем или иным причинам задача выполнена быть не может, то должно быть брошено исключение. Сам метод в общем случае не должен заниматься обработкой собственных исключений, для этого есть вызывающий его код. Метод должен либо выполнить задачу, либо сообщить о невозможности ее выполнения. Вернемся к вашему примеру: Например операция деления одного числа на другое подразумевает, что пользователь может (попробовать) поделить число на ноль. С одной стороны результат этой операции будет исключением, которое можно обработать. С другой стороны можно и не доводить дело до исключения, заранее проверяя вводимые числа. В этом случае должно быть именно вызвано исключение - ваш метод получил некорректные входные данные, и не может правильно произвести операцию деления. Тут интересна такая ваша фраза: С другой стороны можно и не доводить дело до исключения, заранее проверяя вводимые числа. Можно. Но что должен делать код дальше, если проверка не прошла? Вернуть некое магическое значение типа -1 или 0? Это будет некорректно с точки зрения логики. Вывести сообщение об ошибке? Это будет попахивать ошибкой проектирования - отвечать за вывод сообщений об ошибках должен совсем другой код. Появится связность кода, а это очень плохо. Помимо того, существуют такие исключительные ситуации, в которых никакие if-else не помогут. Скажем, не удалось открыть соединение базой данных. Что программа должна делать дальше? Войти в условие и попытаться еще раз открыть его, а затем еще, еще и еще? Вряд ли. Ну а что касается if-else, то их имеет смысл использовать там, где "не сработавший" вариант - всего лишь одно из возможных корректных состояний программы. Резюмирую - метод должен либо выполнить задачу, либо сообщить о невозмождности ее выполнения. Обрабатывать собственные исключения чаще всего не нужно. Следует пробрасывать их вверх. Весьма рекомендую также прочесть у Рихтера главу, посвященную исключениям. Да и вообще саму эту книгуОтвет 2
Нет, я не согласен с Шилдтом. Обычно код структурируется таким образом, что: Большинство операций имеют право выбросить исключение. Они не ловят исключения вызываемого кода, кроме редких случаев, где это действительно нужно. Если у вас происходит ручное управление ресурсами, вам скорее всего пригодится try/finally, а не try/catch try/catch оборачивает как можно большие, внешние блоки программной логики. Например, итерацию главного цикла. По поводу того, где использовать исключения, а где if/else: если операция может ожидаемо завершиться неудачей, используйте ветвление. Если операция завершается неудачно лишь в исключительных случаях, используйте исключения. Пример: если пользователь ввёл текст в editbox, вы не можете исходить из того, что он ввёл число. Используйте такой код: if (int.TryParse(s, out value)) return value; else // покажите message box и не закрывайте диалог В случае, если значение читается из конфигурационного файла, нечисловое значение там, где ожидается число — серьёзная проблема, и код соответственно меняется: return int.Parse(s); // если там не число, бросаем исключение, которое // будет поймано на верхнем уровне операцией чтения конфигурации Дополнительное чтение по теме: http://www.artima.com/intv/handcuffs.htmlОтвет 3
Ветвление - это нормальное поведение программы. Исключения указывают на потенциальную деформацию логической целостности некой модели, от чего ее нужно спасать (закрывать соединения, прекращать работу с объектом и т.п.). Вот в C++ как вы и сказали, исключения добавлены как вспомогательный не обязательный механизм. Но try-catch зачастую читается куда лучше, чем хитроумный контроль за валидностью объекта по многим критериям, специальным переменным.
Комментариев нет:
Отправить комментарий