熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> ASP編程 >> 正文

在VB 2005中定制自己的異常

2013-11-15 12:52:38  來源: ASP編程 

  提要
本文在簡要分析VB 所提供的異常處理機制的同時詳細討論如何用它所提供的異常類定制自己的異常

  結構化異常處理是隨的第一個版本的發行而加入到Visual Basic語言中的結構化異常處理的重要性基於下面兩個原因

   與以前的On Error Goto語句相比而言通過使用一種與該語言其它部分更適應的語法從而使得代碼更具有可讀性

   比以前的On Error Goto語句功能更強而且提供了更為靈活性的控制能力

  一 捕獲並拋出異常

  異常處理是用TryCatchFinallyEnd Try語句實現的其基本語法形式如下

   Try
能夠引發一個異常的代碼
Catch
處理異常的代碼
Finally
實現清理工作的代碼(如關閉數據庫連接等等)
End Try

  Try和End Try語句都是必需的Catch和Finally語句可以共同使用於一個Try塊中但是至少使用其中之一而且可以使用多個Catch語句來處理不同類型的異常如果你有多個Catch塊可以對它們加以排序從最具體的異常類型到最粗略的異常類型

   Try
 能夠引發一個異常的代碼
Catch ex As ArgumentOutOfRangeException
 有可能使用一個缺省值來處理一個無效參數以便使代碼繼續執行
Catch ex As Exception
 處理任何其它類型的異常
Finally
 實現清理工作的代碼(如關閉數據庫連接等等)
End Try

  你也可以在你的代碼中拋出異常當你在代碼中執行一些清理工作時捕獲並拋出異常是很有用的這樣以來一個更高層級的過程可以捕獲它當你創建定制異常類型時拋出異常也很有用

  為了拋出一個異常你可以編寫如下形式的代碼

   Throw New ArgumentOutOfRangeException

  ArgumentOutOfRangeException告訴Throw語句要拋出什麼類型的異常這個ArgumentOutOfRangeException類型僅是NET框架所提供的眾多的類型之一

  二 傳播異常

  當一個異常出現於你的代碼的某處時你可以以三種方式傳播它

  ·什麼也不做而讓它自動地傳播回調用棧(由系統自動處理)

  ·捕獲並再次拋出它這可以允許你在Finally塊中運行一些清理代碼

  ·捕獲它並使用InnerException屬性在另一個異常中包裝該異常並且把這個新的異常拋回調用過程這個InnerException屬性可以讓你維持原始的異常並在一個關系更為密切的異常中存放它的信息

  三 定制自己的異常

  盡框架提供了許多標准異常但你也可以創建拋出和捕獲你自己的定制異常一般地微軟推薦你使用由NET框架所提供的標准異常然而如果你的應用程序僅使用一個標准異常不能滿足需要時你可以創建一個定制異常

  當你創建一個定制異常類型時你就能控制所有的異常屬性你還可以把屬性添加到你的定制異常類中除了把關鍵數據嵌入到Message屬性中外這可以使你有另外一個地方來存儲這些數據而且這可以使得檢索關鍵數據非常簡單而不必在Message屬性外分析它們

  四 定制異常示例

  為了理解定制異常讓我們創建一個很簡單的命令行應用程序來加以具體說明

  該代碼包含一個非常簡單的僅含有一個表Customer的MS Access數據庫一點也不奇怪這個Customer表包含一組顧客記錄(具有CustomerIDfirst namelast nameaddress details共四個字段)該數據庫的實際內容並不重要但是在你的定制異常中實現數據存取是一種非常合適的選擇

  對於本應用程序來說我用VB Express IDE創建了一個新的控制台應用程序

  五 DatabaseException基類

  如果你想創建多個定制異常那麼為這些定制異常創建一個定制基類是個不錯的主意這個基類將繼承自NET框架所提供的SystemException類它還包含三個構造器它們幾乎可以適用於所有你的定制異常本文中示例應用程序的基類稱作DatabaseException其代碼顯示如下

   Public Class DatabaseException
Inherits Exception
Public Sub New()
End Sub
Public Sub New(ByVal message As String)
 MyBaseNew(message)
End Sub
Public Sub New(ByVal message As String ByVal inner As Exception)
 MyBaseNew(message inner)
End Sub
End Class

  這三個構造器都是SystemException類提供的標准的構造器第一個允許你創建一個異常而不必使用任何參數僅需要缺省的異常屬性即可第二個允許你指定一個消息串以用作你的異常的Message屬性最後第三個構造器也允許你指定一個消息串但是它允許你指定一個異常作為第二個參數SystemException類有一個屬性InnerException當你捕獲一個異常並想把它包裝到一個關系更相近的異常的內部時這個屬性很有用通過設置InnerException屬性你可以維持在原始異常中的所有信息

  有關基類最後一點要注意的是在從SystemException類繼承還是從SystemApplicationExeption類繼承的問題上開發者們的意見並不一致大多數的微軟老用戶認為你應該從SystemApplicationException繼承但是也有一些開發者認為應該從SystemException類繼承我也不確定是否它們之間存在什麼技術差距但是我對這兩種情況均作過測試它們都能夠正常工作對於本文示例應用程序我們使用了後面的思想從SystemException類中繼承

  六 定制異常CustomerNotFoundException

  第一個定制異常類是CustomerNotFoundException當你試圖在你的數據庫中查找一個客戶但未找到相應的匹配時你會拋出這個異常實現代碼如下所示

   Public Class CustomerNotFoundException
Inherits DatabaseException
Private m_CustomerID As Long
Public ReadOnly Property CustomerID() As Long
Get
 Return m_CustomerID
End Get
End Property
Public Sub New(ByVal customerID As Long)
 MyBaseNew(Customer ID was not found)
 m_CustomerID = customerID
End Sub
End Class

  這個類繼承自你前面所創建的DatabaseException基類它僅包含一個構造器其參數為customerID當調用這個構造器時你把文本串Customer ID was not found傳遞到基類的構造器以用作Message屬性你還有一個已定義的只讀屬性CustomerID你將使用這個CustomerID屬性來存儲要被作為一個參數傳遞的CustomerID的值它是一個只讀屬性因為把這個值改變為除了引發異常的值以外的值並沒有什麼意義

  七 定制異常DatabaseUnavailableException

  第二個定制異常類是DatabaseUnavailableException當你想連接到一個數據庫並發生一個異常時你就拋出這個異常其實現代碼如下

Public Class DatabaseUnavailableException
Inherits DatabaseException
Public Sub New(ByVal ex As Exception)
 MyBaseNew(The database is not available ex)
End Sub
End Class
  這個類非常相似於你的CustomerNotFoundException類你不用為這個類定義任何其它屬性但是它們的主要區別在於它把一個SystemException作為一個參數並且把它傳遞到你的基類的構造器中這個SystemException參數將成為你的DatabaseUnavailableException的InnerException屬性

  八 Customer類

  Customer類是一個簡單類這個類的構造器使用一個數據庫名和一個CustomerID作為參數並且負責檢索該顧客相應的數據該構造器要做的第一件事情是通過使用ConnectDB方法嘗試建立到數據庫的連接具體代碼如下

Private Sub ConnectDB(ByVal database As String _
 ByRef cn As OleDbConnection)
 cnConnectionString = Provider=MicrosoftJetOLEDB; _
 Data Source= & _
& database &
 Try
  cnOpen()
 Catch ex As Exception
  Throw New DatabaseUnavailableException(ex)
 End Try
End Sub
  你試圖在一個Try語句內打開數據庫連接如果拋出任何異常的話你就會捕獲它並拋出一個DatabaseUnavailableException這個異常用它的InnerException屬性包裝了原始的異常

  如果你成功地連接到數據庫那麼你就試圖使用GetCustomer方法來檢索相應於指定CustomerID的數據詳見下面的代碼

Private Sub GetCustomerData(ByVal cn As OleDbConnection _
 ByVal customerID As Long)
 Dim cmd As New OleDbCommand
 Dim reader As OleDbDataReader
 cmdConnection = cn
 cmdCommandText = SELECT * FROM CUSTOMER WHERE ID = _
& customerID
 reader = cmdExecuteReader
 If readerHasRows Then
  readerRead()
  m_id = readerItem(ID)
  m_firstname = readerItem(Firstname)
  m_lastName = readerItem(Lastname)
  m_street = readerItem(Street)
  m_city = readerItem(City)
  m_state = readerItem(State)
  m_zipCode = readerItem(Zip)
 Else
  Throw New CustomerNotFoundException(customerID)
 End If
End Sub
  上面的代碼中你執行了一個SQL查詢其中使用CustomerID來指定你想要檢索哪個顧客的數據如果查詢返回一個結果那麼你使用從該查詢返回的值設置Customer類的屬性但是如果你沒有得到任何值的話你將使用customerID作為構造器的參數拋出一個CustomerNotFoundException異常這個值將用於設置你的CustomerNotFoundException對象的CustomerID屬性

  九 運行應用程序

  下面的屏幕快照顯示了你的應用程序的運行情況為了運行該應用程序你可以從命令行上調用它並指定一個數據庫名和CustomerID作為參數第一個屏幕快照顯示了一個成功的查詢(見圖第二個屏幕快照拋出一個CustomerNotFoundException異常(見圖第三個屏幕快照拋出一個DatabaseNotAvailableException異常(見圖



成功的查詢

CustomerNotFoundException

DatabaseUnavailableException
  十 總結

  定制異常類型是語言中的一個非常有力的特征NET框架提供了許多標准的異常類型對於大多數應用而言已經足夠了事實上你可能會很少用到標准異常之外的東西但是特殊情況下定制自己的異常會提高你的應用程序的健壯性


From:http://tw.wingwit.com/Article/program/ASP/201311/21799.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.