
- •Тема 5.4. Иерархий классов, интерфейсы и исключения
- •5.4.1. Общие сведения о интерфейсах
- •5.4.2. Организация взаимодействия объектов
- •5.4.4. Обработка исключений в среде .Net Framework
- •5.4.5. Задачи для самостоятельного решения по теме «Иерархий классов, интерфейсы и исключения»
- •5.4.6. Тестовые задания по теме «Иерархий классов, интерфейсы и исключения»
5.4.4. Обработка исключений в среде .Net Framework
При создании программ большое значение имеет обработка исключений – непредвиденных программистом ситуаций, которые могут возникать при выполнении приложения. Например, это может быть попытка сохранить информацию и базе данных на сервере при отсутствии соединения, выход значения индекса массива за допустимые пределы и т. п.
В среде .NET Framework используется структурированный механизм обработки исключений, позволяющий делать это без аварийного завершения программы. К основным преимуществам данного механизма можно отнести использование единых средств поддержки обработки исключений во всех языках среды .NET, возможность создания защищенных блоков кода и фильтрации исключений для эффективного управления ошибками, а также поддержку обработчиков исключений, гарантирующих корректное завершение задач даже при возникновении фатальных ошибок. Среда .NET Framework предоставляет также большое количество встроенных классов исключений, используемых для обработки стандартных ошибок. Например, класс FileNotFoundException содержит информацию об имени файла, сообщение об ошибке и источник исключения, то есть код, содержащий операторы открытия несуществующего файла. Кроме того, среда .NET Framework позволяет программисту создавать собственные классы, которые используются для обработки исключений, возникающих во время работы приложения.
Применение блоков Try и Catch
Обработка исключений основана на использовании блоков Try и Catch. Если при выполнении кода требуется следить за возникновением исключений, то его помещают в блок Try, после чего он становится защищенным. Возникающее исключение перехватывается и обрабатывается кодом, помещенным в блок Catch. Эти блоки работают совместно – нельзя указать блок Try, не задав Catch, и наоборот.
Следующий код демонстрирует, как метод класса отслеживает и обрабатывает исключение. Сначала функция класса пытается обратиться к несуществующему файлу, а при возникновения исключения выполняется его перехват и обработка блоком Catch.
-
Обработка исключения
Imports System.IO Public Class Reader
Private strFilePath As String Property FilePath() As String Get
Return strFilePath End Get Set(ByVal Value As String)
strFilePath = Value End Set End Property
Public Function ReadText() As String Dim sr As StreamReader Dim strFileText As String Try
sr = File.OpenText(strFiiePath) strFileText = sr.ReadToEnd() sr.Close() Return strFileText Catch
Return "Error1 Файл не найден "
End Try
End Function
End Class
С одним блоком Try может быть связано несколько блоков Catch. Каждый из этих блоков можно использовать для перехвата всех исключений, возникающих в блоке Try, или для обработки исключений только определенного типа. Наличие нескольких блоков Catch позволяет динамически реагировать на исключения различных типов. В следующем коде показано использование нескольких блоков Catch для обработки исключений различных типов, которые могут возникнуть при попытке считать с диска текстовый файл.
-
Try
sr = File OpenText(strFilePath)
strFileText = sr.ReadToEnd()
sr Close()
Return strFileText Catch e As DirectoryNotFoundException
Return e.Message Catch e As FileNotFoundException
Return e.Message Catch
Return “Error! File not found.”
End Try
Добавление блока Finally
Для указания кода, который будет выполняться при выходе из блока Try, используется ключевое слово Finally. Блок Finally вызывается независимо от того, выбрасывается исключение или нет, и независимо от причин возникновения такового. Поэтому не важно, завершается блок Try обычным образом или возникает исключение – в любом случае последним выполняется блок кода, определенный ключевым словом Finally В отличие от блоков Catch и Try применение данного блока является необязательным. Рассмотрим пример, когда требуется закрыть файл или соединение с базой данных. Если при выполнении кода внутри блока Try встречается исключение, управление передается коду соответствующего блока Catch, после которого будут выполнены операторы внутри блока Finally. Последний вызывается и в том случае, когда при работе блока Try исключение не возникает. Следующий код демонстрирует, как блок Finally применяется для закрытия соединения с базой данных SQL Server.
-
Добавление блока Finally в оператор Try – Catch
Public Sub MakeConnection()
Dim myConnStnng As String = "user id=sa; " &_ "password=; database=northwind; server=myserver" Dim myConnection As New SqlConnection(myConnStnng) Try
myConnection.Open()
'Код обработки записей в базе данных Catch myException As SqlException
Dim myErrors As SqlErrorCollection = myException.Errors
Dim i As Integer
For i = 0 To myErrors Count - 1
MessageBox Show("Index #" & i & ControlChars.Cr & _
"Error: " & myErrors(i).ToString() & ControlChars.Cr) Next i Finally
myConnection.Close() End Try
End Sub
Обработка собственных исключений
В среде NET псе исключения представлены классами, причем все классы исключений могут быть унаследованы от встроенного класса исключений Exception, являющегося частью пространства имен System, поэтому все исключения представляют собой подклассы этого класса. Встроенные исключения обрабатывают большинство типов ошибок. Главная особенность механизма обработки исключений в среде NET заключается в его способности обработки исключений, заданных программистом. Если при выполнении программы возникает исключение которое не принадлежит ни одному из встроенных классов, можно сформировать собственные исключения, выполняющие обработку ошибок в пользовательском коде. Как правило, так обрабатываются ошибки, которые, возникая при нарушении бизнес-логики приложений, не приводят к аварийному завершению работы программы. Например, при вводе даты заказа указывается месяц, который еще не наступил, – в этом случае необходимо определить собственное исключение. При генерировании исключения создается объект класса System.Exception. Приведенный ниже код представляет собой пример обработки исключения, созданного программистом.
-
Public Sub LogOrder(ByVal OrderNumber As Long, ByVal OrderDate As Date) Try
If OrderDate > Now() Then
Throw New Exception("Order date can not be in the future ") End If
'Выполняемый код . . . Catch
'Код обработки исключения...
End Try
End Sub
Вложенные блоки Try
Иногда в программе возникает ошибка, которую можно исправить с помощью исключения, а затем продолжить выполнение оставшейся части кода блока Try. Например, если произошла ошибка, связанная с попыткой деления на нуль, результату можно присвоить нулевое значение, вывести сообщение об ошибке и продолжить выполнение данной программы. Реализуется это путем использования нескольких вложенных блоков Try. В таком случае код, при выполнении которого может возникнуть ошибка, должен находиться во внешних блока Try и Catch. После обработки исключения во внутреннем блоке Try управление вновь должно быть передано внешнему блоку Try. Далее приведен фрагмент кода, где обрабатывается исключение, которое не перехватывается внутренним блоком Try, но зато перехватывается внешним блоком Try.
-
Try
Try
X1 = X1 / X2 Catch e As DivideZeroException
X1 = 0 End Try
‘Продолжение выполнения кода Catch
‘Код обработки внешнего исключения
End Try
Общедоступные свойства и методы
При объявлении экземпляра класса инициализируются его свойства и методы и, как правило, создаются независимые объекты. Например, в процессе выполнения приложения могут быть созданы два объекта, одно из свойств которых представляет собой значение счетчика; в этом случае при увеличении значения одного счетчика состояние другого не изменяется. Но бывают ситуации, когда нескольким объектам требуется предоставить доступ к общим переменным, например, создать счетчики, которые будут фиксировать количество созданных объектов. Тогда при определении свойства следует указать ключевое слово Shared. Ниже приведен пример простого класса AccountingUti1ities, в котором объявляется свойство DiscountRate. Общие (shared) свойства и методы класса
-
Public Class AccountingUtilities
Private Shared _TaxRate As Single = 0 06 Public Shared Readonly Property TaxRate() As Single Get
Return _TaxRate End Get End Property
End Class
Чтобы получить доступ к общему свойству, не нужно создавать экземпляр этого класса, а достаточно лишь сослаться на него. В следующем примере показано, как обратиться к объявленному выше общему свойству DiscountRate.
-
Public Class Purchase
Public Function CalculateTax(ByVal PurchasePrice As Double) As Double Return PurchasePnce * AccountingUtilities.TaxRate
End Function
End Class
Общие методы незаменимы в тех случаях, когда имеется несколько служебных функций, которые должны быть доступны из любого кода, а не только из кода, определенного в заданной иерархии классов. Использование общих методов позволяет не перегружать программу множеством экземпляров класса для доступа, к какому-то методу. Следует отметить, что общие методы могут использоваться для считывания и присваивания значений только тем свойствам, которые объявлены с модификатором Public Shared. В приведенном ниже коде присутствует общий код,. используемый для подсчета пользователей, которые работают с приложением в данный момент.
-
Public Class UserLog
Private Shared _UserCount As Integer Public Shared Sub IncrementUserCount()
_UserCount += 1 End Sub Public Shared Sub DecrementUserCount()
_UserCount -= 1
End Sub
End Class
Важно, что внешний код получает доступ к общему методу непосредственно, без указания ссылки на экземпляр класса. Далее приведен пример вызова общего метода, определенного ранее в классе
-
UserLog.
Public Class User
Public Sub Logon(ByVal UserName As String, ByVal UserPassword As String) ' Код, выполняющий проверку полномочий ' Если полномочия подтверждены... UserLog.IncrementUserCount()
End Sub
End Class
Общие методы и свойства могут не понадобиться при задании классов приложений, но их использование очень облегчает работу, когда необходимо создать библиотеки базовых классов, поэтому они используются во всех системных классах среды .NET Framework. Приведенная ниже функция демонстрирует применение метода Compare класса System.String. Этот общий метод выполняет сравнение двух строк символов в соответствии с правилами сортировки по алфавиту – возвращает положительное число, если первая строка больше второй, отрицательное, если вторая строка больше первой, и нуль, если строки эквивалентны.
-
Public Function CheckStringOrderAscending(ByVal String1 As String, _
ByVal String2 As String) As Boolean If String.Compare(String1, String2, True) >= 0 Then
Return True End
If End Function