C#-程序設(shè)計(jì)教程第7章_第1頁(yè)
C#-程序設(shè)計(jì)教程第7章_第2頁(yè)
C#-程序設(shè)計(jì)教程第7章_第3頁(yè)
C#-程序設(shè)計(jì)教程第7章_第4頁(yè)
C#-程序設(shè)計(jì)教程第7章_第5頁(yè)
已閱讀5頁(yè),還剩20頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、第7章 程序的生成、異常處理和調(diào)試 7.1 異常處理7.1.1 異常類(lèi)7.1.2 try-catch7.1.3 try-catch-finally7.1.4 多重try結(jié)構(gòu)7.1.5 默認(rèn)異常處理7.1.6 throw7.1.7 用戶自定義異常7.2 Visual Studio 2017的調(diào)試功能目 錄7.1.1 異常類(lèi) 專(zhuān)業(yè)的程序必須能夠處理異常情況。在.NET以前的編程語(yǔ)言中,這常常稱作錯(cuò)誤處理。意外的情況會(huì)生成錯(cuò)誤代碼,程序捕捉這段代碼并采取相應(yīng)的措施。 .NET的公共語(yǔ)言運(yùn)行庫(kù)并不產(chǎn)生錯(cuò)誤代碼。在出現(xiàn)異常情況時(shí),CLR創(chuàng)建一個(gè)稱作異常的特殊對(duì)象,該對(duì)象中的屬性和方法詳細(xì)描述了異常情況以

2、及引起錯(cuò)誤的具體原因。 .NET處理的是異常而不是錯(cuò)誤,因此在.NET中不再使用術(shù)語(yǔ)“錯(cuò)誤處理”,改用“異常處理”。異常處理指的是發(fā)現(xiàn)異常時(shí)采取相應(yīng)措施的.NET技術(shù)。 .NET實(shí)現(xiàn)了系統(tǒng)范圍內(nèi)功能強(qiáng)大的錯(cuò)誤處理方式,.NET中不再使用錯(cuò)誤符號(hào),而使用異常對(duì)象。異常對(duì)象是一個(gè)包含錯(cuò)誤相關(guān)信息的對(duì)象,這些信息顯示為該對(duì)象的屬性。異常對(duì)象是派生于System.Exception類(lèi)的一個(gè)實(shí)例,System.Exception類(lèi)有許多子類(lèi)用于不同的異常情況。7.1 異常處理7.1.1 異常類(lèi) 在C#語(yǔ)言中使用異常類(lèi)和異常處理需要用到幾個(gè)關(guān)鍵字,它們是: try:開(kāi)始一段可能出現(xiàn)錯(cuò)誤的代碼。這段代碼常常

3、稱為 try塊。 catch:為一種類(lèi)型的異常開(kāi)始一個(gè)錯(cuò)誤處理程序。catch跟在try塊的后面,try結(jié)構(gòu)可以有多個(gè)catch塊,每個(gè)catch塊都捕獲不同類(lèi)型的異常。在try塊中遇到錯(cuò)誤時(shí),開(kāi)始執(zhí)行第一個(gè)與異常類(lèi)型匹配的catch塊。 finally:包含在try塊正常結(jié)束時(shí)執(zhí)行的代碼,或者catch塊執(zhí)行完畢后執(zhí)行的代碼。也就是說(shuō),無(wú)論是否檢測(cè)到異常,finally塊中的代碼總是會(huì)執(zhí)行。finally塊一般用于關(guān)閉或刪除資源,例如數(shù)據(jù)庫(kù)連接,如果沒(méi)有清理這類(lèi)資源,代碼就會(huì)出問(wèn)題。 throw:生成一個(gè)錯(cuò)誤,在catch塊中可以用它把異常送回給調(diào)用例程,如果某個(gè)例程檢測(cè)到傳入?yún)?shù)類(lèi)型錯(cuò)誤,

4、也可以用它拋出異常。7.1 異常處理7.1.2 try-catch try-catch 語(yǔ)句由一個(gè) try 塊后跟一個(gè)或多個(gè) catch 子句構(gòu)成,這些子句指定不同的異常處理程序。引發(fā)異常時(shí),公共語(yǔ)言運(yùn)行時(shí) (CLR) 會(huì)查找處理此異常的 catch 語(yǔ)句。如果當(dāng)前執(zhí)行的方法不包含這樣的 catch 塊,則 CLR 會(huì)查看調(diào)用當(dāng)前方法的方法,然后會(huì)遍歷調(diào)用堆棧。如果找不到 catch 塊,則 CLR 會(huì)向用戶顯示一條有關(guān)未處理異常的消息并停止執(zhí)行程序。7.1 異常處理7.1.2 try-catch 雖然可以使用不帶參數(shù)的 catch 子句捕捉任何類(lèi)型的異常,但不推薦這種用法。通常,應(yīng)該只捕捉那

5、些知道如何從中恢復(fù)的異常。因此,應(yīng)該總是指定一個(gè)從 System.Exception 派生的對(duì)象參數(shù)。例如:catch (InvalidCastException e) 7.1 異常處理7.1.2 try-catch 在同一個(gè) try-catch 語(yǔ)句中可以使用一個(gè)以上的特定 catch 子句。這種情況下 catch 子句的順序很重要,因?yàn)闀?huì)按順序檢查 catch 子句。將先捕獲特定程度較高的異常,而不是特定程度較小的異常。如果對(duì) catch 塊進(jìn)行排序以使永遠(yuǎn)不能達(dá)到后面的塊,編譯器將產(chǎn)生錯(cuò)誤。例7-27.1 異常處理7.1.2 try-catch在 catch 塊中可以使用 throw 語(yǔ)

6、句再次引發(fā)已由 catch 語(yǔ)句捕獲的異常。例如:catch (InvalidCastException e) throw (e); / 再次引發(fā)已由 catch 語(yǔ)句捕獲的異常同時(shí)也可以引發(fā)新的異常。下面的例子中將捕捉的異常指定為內(nèi)部異常:catch (InvalidCastException e) / 引發(fā)自定義的新異常 throw new CustomException(Error message here., e);如果要再次引發(fā)當(dāng)前由無(wú)參數(shù)的 catch 子句處理的異常,則使用不帶參數(shù)的 throw 語(yǔ)句。例如:catch throw;7.1 異常處理7.1.2 try-catch

7、在 try 塊內(nèi)部時(shí)應(yīng)該只初始化其中聲明的變量;否則,完成該塊的執(zhí)行前可能發(fā)生異常。例如,在下面的代碼示例中,變量 x 在 try 塊內(nèi)初始化。試圖在 Write(x) 語(yǔ)句中的 try 塊外部使用此變量時(shí)將產(chǎn)生編譯器錯(cuò)誤:使用了未賦值的局部變量。 7.1 異常處理7.1.2 try-catchstatic void Main() int x; try / 不能在此處初始化聲明的變量 x = 123; catch /此處可能會(huì)引發(fā)異常:使用了未賦值的局部變量 Console.Write(x); 7.1 異常處理7.1.3 try-catch-finally finally 塊用于清除 try

8、塊中分配的任何資源,以及運(yùn)行任何即使在發(fā)生異常時(shí)也必須執(zhí)行的代碼。控制總是傳遞給 finally 塊,與 try 塊的退出方式無(wú)關(guān)。 catch 用于處理語(yǔ)句塊中出現(xiàn)的異常,而 finally 用于保證代碼語(yǔ)句塊的執(zhí)行,與前面的 try 塊的退出方式無(wú)關(guān)。 finally 塊中的語(yǔ)句不管異常是否觸發(fā)都會(huì)被執(zhí)行。 catch 和 finally 一起使用的常見(jiàn)方式是:在 try 塊中獲取并使用資源,在 catch 塊中處理異常情況,并在 finally 塊中釋放資源。 7.1 異常處理7.1.3 try-catch-finally 例7-3演示了一個(gè)典型的使用try-catch-finally結(jié)

9、構(gòu)的情景,在try塊中占用了一個(gè)對(duì)文件object類(lèi)型的變量o拆箱并引發(fā)一個(gè)IOException異常,在catch塊中對(duì)異常進(jìn)行捕獲但不做任何處理,在finally塊中輸出i。finally塊保證了不管程序運(yùn)行過(guò)程中是否產(chǎn)生異常都能正確釋放程序運(yùn)行時(shí)所占用的系統(tǒng)資源。 7.1 異常處理7.1.4 多重try結(jié)構(gòu)所謂多重try結(jié)構(gòu)就是指一個(gè)try塊可以嵌套在另一個(gè)try 塊中。在內(nèi)部try塊中生成但沒(méi)有被與該try關(guān)聯(lián)的catch捕獲的異常會(huì)傳播到外部try塊中。 7.1 異常處理7.1.4 多重try結(jié)構(gòu) 在例7-4中,可以被內(nèi)部try處理的異常(在本例中是除以零錯(cuò)誤)允許程序繼續(xù)執(zhí)行。然而

10、,數(shù)組邊界錯(cuò)誤被外部try捕獲,從而導(dǎo)致程序終止。雖然這不是使用多重try結(jié)構(gòu)的唯一原因,但是從前面的程序可以概括出下面的要點(diǎn):多重try結(jié)構(gòu)經(jīng)常用來(lái)以不同的方式處理不同類(lèi)型的錯(cuò)誤。有些錯(cuò)誤的類(lèi)型是災(zāi)難性的,不能修復(fù)。有些則不太重要,可以立即處理。很多程序員使用外部try塊來(lái)捕獲最嚴(yán)重的錯(cuò)誤,允許內(nèi)部try塊處理不太嚴(yán)重的錯(cuò)誤。也可以使用外部try塊作為“捕獲所有異?!钡膲K,以此來(lái)捕獲內(nèi)部try塊沒(méi)有處理的錯(cuò)誤。 7.1 異常處理7.1.5 默認(rèn)異常處理 有時(shí)引發(fā)了一個(gè)異常后,代碼中沒(méi)有catch塊能處理這類(lèi)異常。例如,假定忽略FormatException和通用的catch塊,只有處理Ind

11、exOutOfRangeException的塊。此時(shí),如果引發(fā)一個(gè)FormatException異常,會(huì)發(fā)生什么情況呢? 答案是.NET運(yùn)行庫(kù)會(huì)捕獲它。.NET運(yùn)行庫(kù)可以把整個(gè)程序放在另一個(gè)更大的try快中,每個(gè).NET程序都會(huì)這么做。這個(gè)try塊有一個(gè)catch處理程序,它可以捕獲任何類(lèi)型的異常。如果代碼沒(méi)有處理發(fā)生的異常,程序流就會(huì)退出程序。由.NET運(yùn)行庫(kù)中的catch塊捕獲它。但是,結(jié)果并不是你想像的那樣。代碼的執(zhí)行會(huì)即時(shí)中斷,并給用戶顯示一個(gè)對(duì)話框,通知用戶代碼沒(méi)有處理異常,并給出.NET運(yùn)行庫(kù)能檢索到的異常信息。7.1 異常處理7.1.6 throw throw 語(yǔ)句用于發(fā)出在程序

12、執(zhí)行期間出現(xiàn)反常情況(異常)的信號(hào)。引發(fā)的異常是一個(gè)對(duì)象,該對(duì)象的類(lèi)是從 System. Exception 派生的,例如:class MyException : System.Exception / .throw new MyException(); 通常 throw 語(yǔ)句與 try-catch 或 try-finally 語(yǔ)句一起使用,throw 語(yǔ)句也可以用于重新引發(fā)已捕獲的異常。 在例7-5中,當(dāng)索引超過(guò)數(shù)組長(zhǎng)度時(shí),通過(guò)throw拋出了一個(gè)IndexOutOfRangeException異常實(shí)例。7.1 異常處理7.1.7 用戶自定義異常一般情況下,我們使用系統(tǒng)內(nèi)部提供的異常就足夠了,

13、但是有時(shí)為了特殊的目的,必須使用用戶自定義異常。 無(wú)論我們使用的是系統(tǒng)自定義異常,還是用戶自定義異常,它們都具有相同的異常處理機(jī)制,都包括定義異常類(lèi)、拋出異常對(duì)象和捕獲并處理異常三部分,只不過(guò)是前兩個(gè)過(guò)程已經(jīng)在.NET框架中定義好了。 異常類(lèi)本身和一般的類(lèi)的定義沒(méi)有任何區(qū)別,但是由于使用throw關(guān)鍵字和catch關(guān)鍵字所拋出和捕獲的異常對(duì)象必須是Exception類(lèi)或者Exception類(lèi)子類(lèi)的子類(lèi)對(duì)象,因此所有用戶自定義的異常類(lèi)必須由Exception類(lèi)或者Exception類(lèi)的子類(lèi)派生。7.1 異常處理7.1.7 用戶自定義異常 由于異常屬于意外事件,并不是總是發(fā)生,所以必須有一個(gè)條件判

14、斷語(yǔ)句if(滿足拋出異常條件);然后再拋出異常throw new Excrption,比如:if(y = 0)/如果被除數(shù)為零 /拋出DivideByZeroException異常類(lèi)對(duì)象; throw new DivideByZeroException(); catch關(guān)鍵字用于捕獲在try程序塊中所引發(fā)的異常,根據(jù)該關(guān)鍵字所攜帶的參數(shù)列表的不同具有多種重載方式,但是所有的catch重載塊最多只有一個(gè)被執(zhí)行。比如:catch(DivideByZeroException dz)Console.WriteLine(dz.ToStirng();7.1 異常處理7.1.7 用戶自定義異常 例7-6中,

15、首先我們建立自己的C#異常類(lèi) CustomerException,它要繼承自Exception類(lèi),然后聲明一個(gè)帶參數(shù)構(gòu)造函數(shù),該構(gòu)造函數(shù)調(diào)用基類(lèi)的帶參數(shù)構(gòu)造函數(shù)設(shè)置當(dāng)前異常的消息。在ThrowCustomException函數(shù)中,通過(guò)throw關(guān)鍵字人為拋出一個(gè)CustomerException異常。在Main函數(shù)中通過(guò)try語(yǔ)句塊調(diào)用ThrowCustomException函數(shù),這時(shí)就可以捕獲到用戶自定義的CustomerException異常,然后在catch語(yǔ)句塊中獲取異常實(shí)例,并在控制臺(tái)中輸出異常消息。7.1 異常處理 首先需要了解是斷點(diǎn)(breakpoint):一個(gè)對(duì)調(diào)試器的指令,可

16、以使調(diào)試器運(yùn)行到應(yīng)用程序特定的某一行然后停止。設(shè)置斷點(diǎn)最簡(jiǎn)單的方式是在應(yīng)用程序源代碼的某一特定行左邊點(diǎn)擊。斷點(diǎn)設(shè)置成功后,IDE會(huì)用一個(gè)紅點(diǎn)標(biāo)記斷點(diǎn)7.2 Visual Studio 2017的調(diào)試功能 如果要開(kāi)始對(duì)代碼進(jìn)行調(diào)試可以選擇IDE菜單“調(diào)試開(kāi)始調(diào)試”,或者按F5鍵。程序會(huì)編譯并運(yùn)行到斷點(diǎn),此時(shí)它會(huì)停下來(lái),有一個(gè)黃色箭頭指向下一步要執(zhí)行的語(yǔ)句7.2 Visual Studio 2017的調(diào)試功能到達(dá)斷點(diǎn)后,查看各對(duì)象的值很容易。例如,可以把光標(biāo)放在變量上等一會(huì)兒,就能看到它的值7.2 Visual Studio 2017的調(diào)試功能調(diào)試器IDE還提供了許多有用的窗口,如“局部變量”窗口會(huì)顯示所有局部變量的值7.2 Visual Studio 2017的調(diào)試功能對(duì)象顯示的是類(lèi)型及一個(gè)加號(hào),可以打開(kāi)它們看看內(nèi)部數(shù)據(jù)在調(diào)試狀態(tài)下,按F11鍵可以單步執(zhí)行到下

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論