Идея насчет синтаксиса обработки исключений
Часто приходится писать обработчики исключений, которые делают одно и то же. Например, в следующем кусочке кода нам необходимо среагировать на исключения типа Exception1 и Exception2 записью в лог-файл :
try { // Блок, который может вызвать исключения Exception1, Exception2 // или исключение любого другого типа } catch (Exception1 exc) { logger.WarnException("An exception has been occured : {0}", exc); } catch (Exception2 exc) { logger.WarnException("An exception has been occured : {0}", exc); } |
Проблема в том, что мы не можем никак избежать дублирования кода. Единственный выход – создать отдельный метод-обработчик, в котором и инкапсулировать логику. Но – во-первых, это может оказаться неудобным, поскольку локальные переменные, которые могут понадобиться в обработчике, придется передавать при вызове функции, а во-вторых, сам по себе вызов функции – это еще несколько тактов процессора.
Хотелось бы иметь способ, который бы позволял писать, скажем, следующим образом :
try { // } catch (Exception1, Exception2 exc as Exception) { // exc имеет тип Exception } |
(Предполагается, что типы Exception1 и Exception2 занаследованы от базового класса Exception).
Этот код мог бы преобразовываться в следующий :
Exception exc = null; try { // } catch (Exception1 exc1) { exc = exc1; goto exception_real_handler; } catch (Exception2 exc2) { exc = exc2; goto exception_real_handler; } exception_real_handler: // Работаем с exc как с базовым типом Exception. |
На мой взгляд, это было бы не сложно реализуемым дополнительным синтаксическим сахаром. Вполне применимо к c#, java и C++. Хотя, на счет последнего сомневаюсь, поскольку в С++ на поверку все оказывается несколько сложнее, чем изначально предполагаешь 🙂
Единственное – это необходимо продумать, каким образом компилятор должен реагировать на конструкции вида catch (Exception1, Exception2 exc as Exception) в случае, если Exception1 занаследован от Exception2. Мне видятся несколько путей, по которым мог бы пойти компилятор.
- Выдавать ошибку при компиляции.
Самый жесткий поход. На мой взгляд, это излишне. - Игнорировать наличие более конкретных типов.
Т.е. если идет строчка catch (Exception1, Exception2 exc as Exception), в которой Exception1 : Exception2, то она будет интерпретирована как простой catch (Exception2). Вполне понятный подход. - Игнорировать и выдавать предупреждение – наверное, самый правильный способ.
1