概要:
本文承接上一篇名為“非結構化異常處理--具有非結構化異常處理的電腦”的部落格。本文将電腦的代碼用VB.NET語句寫一個具有結構化異常處理的簡單電腦,主要介紹VB.NET中的結構化異常處理的知識。
确定按鈕的代碼:
Private Sub Button16_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button16.Click
Dim r As Decimal '儲存計算結果的變量
Dim t As String = TextBox1.Text '用于儲存文本框中的算術表達式
Try
Dim space As Integer = t.IndexOf(" ") '搜尋空格位置,如果沒有空格,傳回值為0
'字元串的取子符方法,第二個參數小于0,則将産生的錯誤号為5的異常
Dim s1 As String = t.Substring(0, space) '通過取子串的方法獲得第一個運算數
Dim op As String = t.Substring(space + 1, 1) '通過取字串方法獲得運算符
Dim s2 As String = t.Substring(space + 3) '通過取子串的方法獲得第二個運算數
Dim arg1, arg2 As Integer
arg1 = Convert.ToInt32(s1) : arg2 = Convert.ToInt32(s2)
Select Case op
Case "+" : r = arg1 + arg2
Case "-" : r = arg1 - arg2
Case "*" : r = arg1 * arg2
Case "/" : r = arg1 / arg2
Case Else
MsgBox("輸入的運算符有誤!")
Exit Sub
End Select
TextBox1.Text = CStr(r) '顯示結果
Exit Sub
Catch Exam As System.OverflowException '算術溢出異常處理
MsgBox("算術運算溢出", , "溢出提示")
Catch Exam As System.ArgumentException '參數數目不夠或值不在範圍内異常處理
MsgBox("參數有誤,應輸入運算符和第二個運算數!", , "參數有誤提示")
Catch Exam As System.FormatException '參數格式不正确異常處理
MsgBox("字元串中出現了非數字字元", , "參數格式不正确提示")
Catch Exam As SystemException '其他異常處理
MsgBox("其他異常,錯誤号為:" & Err.Number & Chr(10) & Chr(13) & "錯誤提示:" & Err.Description)
End Try
End Sub
理論部分:
程式中的語句“Try…Catch…Finally…End Try”是專門用于結構化異常處理的語句。
結構化異常處理能幫助程式員建立和維護具有可靠,全面的錯誤處理程式的項目。在結構化異常進行中,代碼塊是封裝的,每個塊有一個或幾個關聯的處理程式。每個處理程式對它處理的異常類型指定某種形式的篩選條件。當受保護的代碼塊内的代碼引發異常時,按順序搜尋相應的異常處理集,并執行第一個與篩選條件比對的處理程式。“Try…Catch…Finally…EndTry”語句用于處理給定代碼段中可能出現的某些或所有錯誤,而同時代碼仍保持運作。該語句的格式與功能如下:
格式:
Try
Try語句塊 ‘該語句塊可能會引發異常
[Catch [exception [As type]] [When expression] ‘用于捕獲Try語句中的異常
Catch] ‘Catch語句塊用來對捕獲的錯誤進行處理
………….
[Finally
[finally語句塊]] ‘Finally語句塊,存放異常處理後執行的代碼
End Try
功能:
執行“Try語句塊”中的語句,如果産生異常,則系統自動查找離可以處理這個異常最近的Catch語句,并且在運作時決定異常類型。首先,會尋找包含此代碼的Try塊。當找到Try塊時,系統将從與此Try塊相關聯的一個或多個Catch塊中,尋找一個符合條件的塊執行。這個查找一個進行直到找到可以處理目前的異常的Catch為止。找到異常處理塊後,将執行其中的處理代碼,在處理代碼中進行異常處理或重新抛出異常。無論是否有異常發生,均會執行Finally塊中的“語句組n+1”。
說明:
1.[exception [As type]] 用來指定捕獲指定類型或其派生類型的異常。例如,若此項為“Ex AS DivideByZeroException”,則在執行Try塊時發生了整數除數為0的異常,将執行該Catch語句塊。
2. [When expression] 用來指定執行該Catch語句塊必須滿足的條件,通常要根據Err對象中的某些資訊構成表達式。例如,若此項為“Where Err.Number=6”,則在執行Try塊時發生了資料溢出異常,将執行該Catch語句塊。
3. 執行Try塊語句發生異常時,将從第一個Catch塊開始尋找比對的異常,找到第一個比對的異常時,執行其中的Catch語句塊。執行過後,如果有Finally語句塊則執行該語句塊,如果沒有那麼跳出Try語句。
4.可以省略Catch塊。由于沒有Catch塊,程式執行過程中發生異常,如果有Finally塊則将直接執行該塊中的代碼,否則将直接中斷。
5.可以省略Finally塊。但是Catch和Finally塊不能同時省略。
代碼解釋:
1. 一般處理異常時,使用若幹個Catch塊把感興趣的異常處理完,再用一個Catch塊,處理剩餘的其他異常,此時Catch塊中的變量應是“System.Exception”類的變量,是以所有的異常由該類派生。
2. 可以通過不帶參數的Catch來捕獲Try塊中的所有異常。程式中的語句“Catch ExamAsSystemException”,可以直接寫成“Catch”,效果是一樣的。
3. 在Catch語句中列舉類型時,要先列舉在異常內建體系結構中最具體的類型,最後才列舉System.Exception。如果在上例中我們将“
System.ArgumentException”類的異常放在“System.Exception”後面,提示資訊将為“發生了其他異常”,原因是執行了第一個比對的Catch語句塊
歸納說明:
除了非結構化異常處理外,VB.NET還支援結構化異常處理,使用的語句時“Try…Catch…Finally…End Try”語句,進而使VB.NET,C++與C#等語言并列起來。編寫結構化異常處理程式時,一個原則是:在Catch語句中列舉異常類型時,要先列舉在異常繼承體系結構中最具體的類型,最後才列舉System.Exception。