Более элегантная обработка исключений, чем несколько блоков захвата?
Используя C#, есть ли лучший способ обрабатывать несколько типов исключений, а не кучу уродливых блоков catch?
Что считается лучшей практикой для ситуаций такого типа?
Например:
try
{
// Many types of exceptions can be thrown
}
catch (CustomException ce)
{
...
}
catch (AnotherCustomException ace)
{
...
}
catch (Exception ex)
{
...
}
8 ответов
На мой взгляд, куча "некрасивых" блоков улова - лучший способ справиться с этой ситуацией.
Причина, по которой я предпочитаю это, заключается в том, что это очень явно. Вы явно указываете, какие исключения вы хотите обработать, и как они должны обрабатываться. Другие формы попыток объединить обработку в более сжатые формы в большинстве случаев теряют читабельность.
Мой совет - придерживаться этого и обрабатывать исключения, которые вы хотите обработать явно, каждое в своем блоке catch.
Я согласен с Ридом: это лучший подход.
Я бы добавил эти комментарии:
Только поймать то, что вы собираетесь сделать что-то. Если вы не можете решить проблему, нет смысла отлавливать конкретное исключение.
Не переусердствуйте с использованием блоков catch. Во многих случаях, когда вы не можете разрешить исключение, лучше просто позволить исключению всплыть до центральной точки (такой как Page_Error) и перехватить его там. Затем вы регистрируете исключение и отображаете сообщение для пользователя.
Единственное, что вы можете сделать, это эмулировать фильтры исключений VB.NET:
try {
DoSomething();
} catch (Exception e) {
if (!ex is CustomException && !ex is AnotherCustomException) {
throw;
}
// handle
}
Иногда это лучше, иногда нет. Я бы в основном использовал его, если бы в обработчике была какая-то общая логика, которую я хотел, но исключения не разделяют базовый тип.
К сожалению, C# не имеет пользовательских фильтров исключений, таких как VB.NET, поэтому вы ограничены:
- Поймать общего предка на все исключения. Это может или не может быть тем, что вы хотите, потому что могут быть другие типы исключений-потомков, которые вы не хотите перехватывать.
- Перемещение логики обработки исключений в другой метод и вызов ее из каждого обработчика.
- Повторение логики исключений для каждого обработчика.
- Перемещение логики обработки исключений на язык, который поддерживает фильтры, такие как VB.NET.
Вы должны проверить блок обработки исключений Enterprise Library. Он позволяет гораздо более точно контролировать зерно исключений с помощью политик (политики обертывания, политики распространения, политики замены, политики ведения журнала и т. Д.). Вы можете использовать его для стандартизации способа кодирования блока исключений и использования конфигурации для точной обработки того, что происходит с конкретный тип исключения.
Разве это не хорошо?
Если вы хотите обработать только одно исключение:
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
}
хорошо, не хорошо?
Поймай только то, что нужно разрешить конкретно и оставь
catch(Exception e)
{
}
для всего остального (или пропустить это и дать это исключение в стек)