Таким образом, если вы хотите определить блок catch
CarIsDeadException и ArgumentOutOfRangeException, то можно было бы написать следующий код:// Этот код скомпилируется без проблем.
Console.WriteLine("***** Handling Multiple Exceptions *****\n");
Car myCar = new Car("Rusty", 90);
try
{
// Вызвать исключение выхода за пределы диапазона аргумента.
myCar.Accelerate(-10);
}
catch (CarIsDeadException e)
{
Console.WriteLine(e.Message);
}
catch (ArgumentOutOfRangeException e)
{
Console.WriteLine(e.Message);
}
// Этот блок будет перехватывать все остальные исключения
.// помимо CarIsDeadException и ArgumentOutOfRangeException
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadLine();
На заметку!
Везде, где только возможно, отдавайте предпочтение перехвату специфичных классов исключений, а не общего классаSystem.Exception. Хотя может показаться, что это упрощает жизнь в краткосрочной перспективе (поскольку охватывает все исключения, которые пока не беспокоят), в долгосрочной перспективе могут возникать странные аварийные отказы во время выполнения, т.к. в коде не была предусмотрена непосредственная обработка более серьезной ошибки. Не забывайте, что финальный блок catch, который работает с System.Exception, на самом деле имеет тенденцию быть чрезвычайно общим.Общие операторы catch
В языке C# также поддерживается "общий" контекст catch
// Общий оператор catch.
Console.WriteLine("***** Handling Multiple Exceptions *****\n");
Car myCar = new Car("Rusty", 90);
try
{
myCar.Accelerate(90);
}
catch
{
Console.WriteLine("Something bad happened...");
// Произошло что-то плохое...
}
Console.ReadLine();
Очевидно, что это не самый информативный способ обработки исключений, поскольку нет никакой возможности для получения содержательных данных о возникшей ошибке (таких как имя метода, стек вызовов или специальное сообщение). Тем не менее, в C# такая конструкция разрешена, потому что она может быть полезной, когда требуется обрабатывать все ошибки в обобщенной манере.
Повторная генерация исключений
Внутри логики блока try
throw в блоке catch. В итоге исключение передается вверх по цепочке вызовов, что может оказаться полезным, если блок catch способен обработать текущую ошибку только частично:// Передача ответственности.
...
try
{
// Логика увеличения скорости автомобиля...
}
catch(CarIsDeadException e)
{
// Выполнить частичную обработку этой ошибки и передать ответственность.
throw;
}
...
Имейте в виду, что в данном примере кода конечным получателем исключения CarIsDeadException
Также обратите внимание на неявную повторную генерацию объекта CarIsDeadException
throw без аргументов. Дело в том, что здесь не создается новый объект исключения, а просто передается исходный объект исключения (со всей исходной информацией). Это позволяет сохранить контекст первоначального целевого объекта.Внутренние исключения