Более элегантная обработка исключений, чем несколько ловушек?
Используя С#, есть ли лучший способ обрабатывать несколько типов исключений, а не пучок уродливых блоков catch?
Что считается лучшей практикой для такого типа ситуаций?
Например:
try
{
// Many types of exceptions can be thrown
}
catch (CustomException ce)
{
...
}
catch (AnotherCustomException ace)
{
...
}
catch (Exception ex)
{
...
}
Ответы
Ответ 1
На мой взгляд, куча "уродливых" блоков catch - лучший способ справиться с этой ситуацией.
Я предпочитаю, чтобы это было очень явным. Вы явно указываете, какие исключения вы хотите обрабатывать, и как их следует обрабатывать. Другие формы попыток объединить обработку в более сжатые формы теряют читаемость в большинстве случаев.
Моим советом было бы придерживаться этого и обрабатывать исключения, которые вы хотите обработать явно, каждый в своем собственном блоке catch.
Ответ 2
Я согласен с Ридом: это лучший подход.
Я бы добавил следующие комментарии:
Только поймите то, о чем вы собираетесь что-то делать. Если вы не можете исправить эту проблему, нет смысла в поиске конкретного исключения.
Не переусердствуйте от использования блоков catch. Во многих случаях, когда вы не можете разрешить исключение, лучше всего просто дать исключению пузырь до центральной точки (например, Page_Error) и поймать ее там. Затем вы регистрируете исключение и выводите сообщение пользователю.
Ответ 3
О том, что вы можете сделать, это только эмуляция фильтров исключений VB.NET:
try {
DoSomething();
} catch (Exception e) {
if (!ex is CustomException && !ex is AnotherCustomException) {
throw;
}
// handle
}
Иногда это лучше, иногда нет. Я бы в основном использовал его, если в обработчике была какая-то общая логика, но исключения не имеют базового типа.
Ответ 4
К сожалению, С# не имеет фильтров пользовательских исключений, таких как VB.NET, поэтому вы ограничены:
- Ловля общего предка ко всем исключениям. Это может быть или не быть тем, что вы хотите, потому что могут быть другие типы исключений потомков, которые вы не хотите улавливать.
- Перемещение логики обработки исключений в другой метод и вызов этого из каждого обработчика.
- Повторение логики исключений для каждого обработчика.
- Перемещение логики обработки исключений на язык, который поддерживает фильтры, такие как VB.NET.
Ответ 5
Если вам нужно написать действительно большое количество кода, как это, я бы предложил проверить AOP. Я лично использую PostSharp.
Затем вы можете скрыть весь код обработки исключений в аспектах.
Ответ 6
Вы должны проверить блок управления Блок обработки исключений. Это позволяет гораздо более мелкозернистое управление исключениями посредством политик (политики упаковки, политики распространения, политики замещения, политики ведения журналов и т.д.). Вы можете использовать его для стандартизации способа кодирования блока исключений и использования конфигурации для обработки точно, что происходит с конкретный тип исключения.
Ответ 7
Неужели это плохо?
Если вы хотите обработать только одно исключение:
try
{
// Many types of exceptions can be thrown
}
catch (TheExceptionIWantToHandle ex)
{
// handle it
}
catch (Exception ex)
{
// suppress all other exceptions
}
Если вы хотите обрабатывать все исключения, кроме одного:
try
{
// Many types of exceptions can be thrown
}
catch (TheExceptionIDoNotWantToHandle ex)
{
// suppress all other exceptions
}
catch (Exception ex)
{
// handle it
}
хорошо, не хорошо?
Ответ 8
Поймайте только то, что вам нужно для конкретного решения, и оставьте
catch(Exception e)
{
}
для всего остального (или пропустить его и передать исключения в стек)