Ловить два исключения в одном блоке catch?
У меня есть метод, который может генерировать два разных исключения: CommuncationException
и SystemException
. В обоих случаях я делаю тот же трехстрочный кодовый блок.
try {
...
}
catch (CommunicationException ce) {
...
}
catch {SystemExcetion se) {
...
}
Есть ли возможность сделать это так?
try {
...
}
catch (CommunicationException ce, SystemException se) {
...
}
Тогда мне не пришлось бы писать этот много кода. Я знаю, что я могу извлечь обработку исключений для частного метода, но поскольку код имеет длину всего 3 строки, определение метода будет содержать больше кода, чем само тело.
Ответы
Ответ 1
На самом деле вы можете поймать только SystemException
, и он будет обрабатывать CommunicationException
тоже, потому что CommunicationException
получен из SystemException
catch (SystemException se) {
... //this handles both exceptions
}
Ответ 2
Если вы можете обновить приложение до С# 6, вам повезло. Новая версия С# реализовала фильтры исключений. Поэтому вы можете написать это:
catch (Exception ex) when (ex is CommunicationException || ex is SystemException) {
//handle it
}
Некоторые считают, что этот код такой же, как
catch (Exception ex) {
if (ex is CommunicationException || ex is SystemException) {
//handle it
}
throw;
}
Но это не так. На самом деле это единственная новая функция в С# 6, которую невозможно эмулировать в предыдущих версиях. Во-первых, повторный бросок означает больше накладных расходов, чем пропуск улова. Во-вторых, это не семантически эквивалентно. Новая функция сохраняет неиспользуемый стек при отладке вашего кода. Без этой функции аварийный сброс менее полезен или даже бесполезен.
См. обсуждение этого вопроса в CodePlex. И пример показывающий разницу.
Ответ 3
К сожалению, нет способа. Синтаксис, который вы использовали, недействителен, и падение, как в switch-statement, также невозможно. Я думаю, вам нужно пойти с приватным методом.
Немного взломанный рабочий процесс будет примерно таким:
var exceptionHandler = new Action<Exception>(e => { /* your three lines */ });
try
{
// code that throws
}
catch(CommuncationException ex)
{
exceptionHandler(ex);
}
catch(SystemException ex)
{
exceptionHandler(ex);
}
Вам нужно решить для себя, если это имеет смысл.
Ответ 4
Нет, ты не можешь так поступать. Единственный способ, которым я знаю, - поймать общее исключение, а затем проверить, какой он тип:
try
{
...
}
catch(Exception ex)
{
if(ex is CommunicationException || ex is SystemException)
{
...
}
else
{
... // throw; if you don't want to handle it
}
}
Ответ 5
Что насчет
try {
...
}
catch (CommunicationException ce) {
HandleMyError(ce);
}
catch {SystemExcetion se) {
HandleMyError(se);
}
private void HandleMyError(Exception ex)
{
// handle your error
}
Ответ 6
Возможный дубликат
Захват нескольких исключений сразу?
Я цитирую ответ здесь:
catch (Exception ex)
{
if (ex is FormatException ||
ex is OverflowException)
{
WebId = Guid.Empty;
return;
}
else
{
throw;
}
}
Ответ 7
Поскольку вы делаете то же самое для обоих типов исключений, вы можете просто пойти:
try
{
//do stuff
}
catch(Exception ex)
{
//normal exception handling here
}
Используйте только явные типы исключений, если вам нужно сделать что-то уникальное для него.