Шрифт:
Заметьте, что в данном случав мы передали объект FileNotFoundException конструктору CarIsDeadException в виде второго параметра. Сконфигурировав этот новый объект, мы направляем его по стеку вызовов следующему вызывающему объекту, в данном случае по отношению к методу Main.
С учетом того, что после Main "следующих вызывающих объектов" для обработки исключений нет, мы снова должны увидеть диалоговое окно с сообщением об ошибке. Во многом подобно генерированию вторичных исключений, запись внутренних исключений обычно оказывается полезной только тогда, когда вызывающий объект имеет возможность красиво обработать такое исключение. В этом случае логика catch вызывающей стороны может использовать свойство InnerException для получения подробной информации об объекте внутреннего исключения.
Блок finally
В рамках try/catch можно также определить необязательный блок finally. Задача блока finally – обеспечить безусловное выполнение некоторого набора операторов программного кода, независимо от наличия или отсутствия исключения (любого типа). Для примера предположим, что вы хотите всегда выключать радио автомобиля перед выходом из Main, независимо от исключений.
Если вы не включите в конструкцию блок finally, то радио не будет выключаться, когда обнаруживается исключение (что может быть или не быть проблемой). В более реальном сценарии, когда приходится освобождать ресурсы объектов, закрывать файлы, отключаться от баз данных и т.д., блок finally может гарантировать соответствующую "уборку".
Что и чем генерируется
С учетом того, что методы в .NET Framework могут генерировать любое число исключений (в зависимости от обстоятельств), логичным кажется следующий вопрос: "Как узнать, какие именно исключения могут генерироваться тем или иным методом библиотеки базовых классов?" Ответ прост: это можно выяснить в документации .NET Framework 2.0 SDK. В системе справки для каждого метода указаны и исключения, которые может генерировать данный член. В Visual Studio 2005 вам предлагается альтернативный, более быстрый вариант: чтобы увидеть список всех исключений (если таковые имеются), генерируемых данным членом библиотеки базовых классов, достаточно просто задержать указатель мыши на имени члена в окне программного кода (рис. 6.6).
Рис. 6.6. Идентификация исключений, генерируемых данным методом
Тем программистам, которые пришли к изучению .NET, имея опыт работы с Java, важно понять. что, члены типа не получают множество исключений из прототипа (другими словами, .NET не поддерживает типизацию исключений). Поэтому вам нет необходимости обрабатывать абсолютно все исключения, генерируемые данным членом. Во многих случаях можно обработать все ошибки путем захвата только System.Exception.
Однако если необходимо обработать конкретные исключения уникальным образом, то придется использовать множество блоков catch, как была показано в данной главе.
Исключения, оставшиеся без обработки