Иллюстрированный самоучитель по Visual Basic .NET

Анализ исключений. Наличие нескольких секций Catch.

Совпадение считается обнаруженным, если текущее исключение относится к типу, указанному в заголовке секции Catch, или производному от него. Например, класс FileNotFoundException является производным от I0Exception, поэтому следующий фрагмент неправилен:

Try
ProcessFile(args(1))
Catch indexProblem As IndexOutOfRangeException
Console.WriteLinet"ERROR = No file name supplied")
Catch IOProblem As System.IO.l0Exception
Console. WriteLinet "ERROR = can't process file named " & args(D)
Catch fileNotFound As System.IO.FileNotFoundException
End Try

Специализированное исключение FileNotFoundException будет поглощено предыдущей секцией, перехватывающей исключение базового класса l0Exception.

Из сказанного следует, что размещать секции Catch после секции Catch e As Exception бесполезно. Указание типа Exception в первой секции Catch автоматически перекрывает все остальные секции (кстати говоря, секция Catch без явного указания типа исключения считается эквивалентной Catch e As Exception). Также следует учитывать, что пустая секция с условием Catch e As Exception напоминает очень опасную конструкцию On Error Resume из прежних версий VB.

Несмотря на все опасности, связанные с перехватом обобщенных исключений Catch e As Exception, эту проверку рекомендуется включать в последнюю секцию Catch любого блока Try – особенно на стадии разработки и тестирования, поскольку эта проверка помогает лучше изолировать ошибки. Если все остальные способы не помогают, попробуйте вывести содержимое стека на консоль или в файл методом StackTrace класса обобщенного исключения Exception. Пример:

Try
ProcessFile(argsd))
Catch indexProblem As IndexOutOfRangeException
Console.WriteLine("ERROR – No file name supplied")
Catch fnf As System.IO.FileNotFoundException
Console.WriteLinet"ERROR – FILE NOT FOUND")
Catch ioProblem As System.IO.IOException
Console.WriteLine("ERROR – can't process file named " & args(1))
Catch e As Exception
Console.WriteLinet"Please inform the writer of this program " & _
"of this message")
Console.Writete.StackTrace)
End Try

Что произойдет, если возникшее исключение не подойдет ни к одной из секций Catch, а в конце блока Try-Catch отсутствует универсальная секция Catch e As Exception? В этом случае исключение передается в секцию Try верхнего уровня, заключающую код внутренней секции Try. Если подходящая секция Catch не будет найдена и во внешней секции Try, поиск продолжается в методе, от которого поступил вызов. Вероятно, именно это и произойдет при вызове метода ProcessFiIe из предыдущего примера – метод ProcessFilе передает все необработанные исключения (в форме объекта Exception) в процедуру Sub Main.

Примечание
Если исключение не будет перехвачено ни одной секцией Try в методе, управление переходит в секцию Finally, а затем немедленно передается за пределы метода. Таким образом, обработку исключений можно рассматривать как невероятно мощную (и притом интеллектуальную) разновидность GoTo. Интеллектуальность заключается в автоматическом выполнении завершающего кода в секции Finally
.

В общем случае, если исключение не было обработано программой вплоть до точки входа в приложение, .NET выводит сообщение с описанием исключения и содержимое стека с информацией обо всех вызванных методах на момент возникновения исключения.

В VB.NET секция Catch может дополняться условием When, расширяющим возможности ее применения. Синтаксис выглядит следующим образом:

Catch badnameException When theName – String.Empty
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.