В процессе выполнения программы нередко возникают такие ситуации, которые трудно или даже невозможно предусмотреть во время создания программы. Например, при передаче файла по сети может неожиданно оборваться сетевое подключение. Такие ситуации называются исключениями. Чтобы программа неожиданно не зависла в таких ситуациях, программисту нужно вводить в нее обработку исключений. Для обработки исключений в языке VB.NET имеется конструкция Try...Catch..Finally. Ее использование выглядит следующим образом:
Sub Main()
Dim a(3) As Integer
Try
a(5) = 3
Catch ex As Exception
Console.WriteLine(ex.Message)
Finally
Console.WriteLine("Finally block")
End Try
Console.ReadLine()
End Sub
В данном случае у нас как раз и возникает исключение, так как в массиве a только 4 элемента, а мы пытаемся присвоить значение шестому элементу.
При использовании блока Try...Catch..Finally сначала выполняются все инструкции между операторами Try и
Catch.
И если вдруг в каком-то месте кода возникает исключение, то обычный порядок выполнения кода останавливается и программа переходит к выражению Catch.
Это выражение имеет следующий синтаксис: Catch имя_переменной As тип_исключения. В данном случае у нас объявляется переменная ex, которая
имеет тип Exception. При чем если возникшее исключение не является исключением типа, указанного в выражении Catch, то оно не обрабатывается,
а программа просто зависает или выбрасывает сообщение об ошибке. Так как тип Exception является базовым типом для всех исключений, то в
выражении Catch ex As Exception абсолютно все исключения.
В нашем случае мы просто выводим сообщение об исключении на экран с помощью свойства Message, определенное в классе Exception.
Далее в любом случае выполняется блок после оператора Finally. Но этот блок необязательный, и его можно при обработке исключений опускать.
В случае, если в ходе программы исключений не возникнет, то программа не будет выполнять блок Catch, сразу перейдет к блоку Finally, если он имеется.
Мы можем создать свои собственные классы исключений, которые будут обрабатывать нежелательные ситуации. Для примера возьмем класс
Algorithm, который мы сделали в одной из глав предыдущей части:
Public Class Algorithm
Public Shared Function Factorial(x As Integer) As Integer
If (x = 1) Then
Return 1
Else
Return x * Factorial(x - 1)
End If
End Function
Public Shared Function Fibbonachi(x As Integer) As Integer
If x = 0 Then
Return 1
ElseIf x = 1 Then
Return 1
Else
Return Fibbonachi(x - 1) + Fibbonachi(x - 2)
End If
End Function
End Class
Факториал и последовательность Фиббоначи определены только для положительных чисел, поэтому если мы передадим в функцию отрицательное число,
возникнет исключительная ситуация. Чтобы ее обработать и создадим класс NegativeNumberException:
Public Class NegativeNumberException
Inherits Exception
Sub New()
MyBase.New("В качестве параметра передано отрицательное число")
End Sub
End Class
В этом классе по сути мы только передаем сообщение в конструктор базового класса. Теперь вызовем обработку исключения в методе Factorial с помощью ключевого слова Throw:
Public Shared Function Factorial(x As Integer) As Integer
If x < 0 Then Throw New NegativeNumberException()
If (x = 1) Then
Return 1
Else
Return x * Factorial(x - 1)
End If
End Function
И теперь, если мы передадим в этот метод отрицательные значения, в блоке Try...Catch будет обрабатываться исключение NegativeNumberException:
Try
Console.WriteLine(Algorithm.Factorial(-1))
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try