// Вызвать исключение выхода за пределы диапазона аргумента.
myCar.Accelerate(-10);
}
catch(Exception e)
{
// Обработать все остальные исключения?
Console.WriteLine(e.Message);
}
catch (CarIsDeadException e)
{
Console.WriteLine(e.Message);
}
catch (ArgumentOutOfRangeException e)
{
Console.WriteLine(e.Message);
}
Console.ReadLine;
Представленная выше логика обработки исключений приводит к возникновению ошибок на этапе компиляции. Проблема в том, что первый блок catch
System.Exception (с учетом отношения "является"), в том числе CarIsDeadException и ArgumentOutOfRangeException. Следовательно, два последних блока catch в принципе недостижимы!Запомните эмпирическое правило: блоки catch
catch перехватывал наиболее специфическое исключение (т.е. производный тип, расположенный ниже всех в цепочке наследования типов исключений), а последний catch — самое общее исключение (т.е. базовый класс имеющейся цепочки наследования: System.Exception в данном случае).Таким образом, если вы хотите определить блок 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
{
Бьёрн Страуструп , Ирина Сергеевна Козлова , Бьерн Страуструп , Валерий Федорович Альмухаметов
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT