淺談C#中簡略的異常激發與處置操作。本站提示廣大學習愛好者:(淺談C#中簡略的異常激發與處置操作)文章只能為提供參考,不一定能成為您想要的結果。以下是淺談C#中簡略的異常激發與處置操作正文
異常和異常處置
C# 說話的異常處置功效可贊助您處置法式運轉時湧現的任何不測或異常情形。異常處置應用 try、catch 和 finally 症結字測驗考試某些操作,以處置掉敗情形,雖然這些操作有能夠掉敗,但假如您肯定須要如許做,且願望在過後清算資本,便可以測驗考試如許做。公共說話運轉時 (CLR)、.NET Framework 或任何第三方庫或許運用法式代碼都可以生成異常。異常是應用 throw 症結字創立的。
許多情形下,異常能夠不是由代碼直接挪用的辦法激發,而是由挪用客棧中地位更靠下的另外一個辦法所激發。在這類情形下,CLR 將睜開客棧,查找能否無方法包括針對該特定異常類型的 catch 塊,假如找到如許的辦法,就會履行找到的第一個如許的 catch 塊。假如在挪用客棧中的任何地位都沒有找到恰當的 catch 塊,就會終止該過程,並向用戶顯示一條新聞。
此示例中應用一個辦法檢測能否有被零除的情形;假如有,則捕捉該毛病。假如沒有異常處置,此法式將終止並發生“DivideByZeroException 未處置”毛病。
class ExceptionTest { static double SafeDivision(double x, double y) { if (y == 0) throw new System.DivideByZeroException(); return x / y; } static void Main() { // Input for test purposes. Change the values to see // exception handling behavior. double a = 98, b = 0; double result = 0; try { result = SafeDivision(a, b); Console.WriteLine("{0} divided by {1} = {2}", a, b, result); } catch (DivideByZeroException e) { Console.WriteLine("Attempted divide by zero."); } } }
異常概述
異常具有以下特色:
應用異常
在 C# 中,法式中的運轉時毛病經由過程應用一種稱為“異常”的機制在法式中流傳。 異常由碰到毛病的代碼激發,由可以或許更正毛病的代碼捕獲。 異常可由 .NET Framework 公共說話運轉時 (CLR) 或由法式中的代碼激發。 一旦激發了一個異常,這個異常就會在挪用客棧中往上流傳,直到找到針對它的 catch 語句。 未捕捉的異常由體系供給的通用異常處置法式處置,該處置法式會顯示一個對話框。
異常由從 Exception 派生的類表現。 此類標識異常的類型,並包括具體描寫異常的屬性。 激發異常觸及到創立一個異常派生類的實例,設置裝備擺設異常的屬性(可選),然後應用 throw 症結字激發該對象。 例如:
class CustomException : Exception { public CustomException(string message) { } } private static void TestThrow() { CustomException ex = new CustomException("Custom exception in TestThrow()"); throw ex; }
在激發異常以後,運轉時檢討以後語句以肯定它能否在 try 塊中。 假如是,則檢討與該 try 塊聯系關系的任何 catch 塊,以肯定它們能否可以或許捕捉該異常。 Catch 塊平日會指定異常類型;假如該 catch 塊的類型與異常或異常的基類的類型雷同,則該 catch 塊就可以夠處置該辦法。 例如:
static void TestCatch() { try { TestThrow(); } catch (CustomException ex) { System.Console.WriteLine(ex.ToString()); } }
假如激發異常的語句不在 try 塊中,或許包括該語句的 try 塊沒有婚配的 catch 塊,運轉時將檢討挪用辦法中能否有 try 語句和 catch 塊。 運轉時將在挪用客棧中向上持續搜刮兼容的 catch 塊。 在找到並履行 catch 塊以後,掌握權將傳遞給 catch 塊以後的下一個語句。
一個 try 語句能夠包括多個 catch 塊。 將履行第一個可以或許處置該異常的 catch 語句;任何後續的 catch 語句都將被疏忽,即便它們是兼容的也如斯。 是以,在任何情形下都應當依照從最詳細(或許派生水平最高)到最不詳細這一次序分列 catch 塊。 例如:
static void TestCatch2() { System.IO.StreamWriter sw = null; try { sw = new System.IO.StreamWriter(@"C:\test\test.txt"); sw.WriteLine("Hello"); } catch (System.IO.FileNotFoundException ex) { // Put the more specific exception first. System.Console.WriteLine(ex.ToString()); } catch (System.IO.IOException ex) { // Put the less specific exception last. System.Console.WriteLine(ex.ToString()); } finally { sw.Close(); } System.Console.WriteLine("Done"); }
履行 catch 塊之前,運轉時會檢討 finally 塊。 Finally 塊使法式員可以或許消除中斷的 try 塊能夠遺留下的任何隱約狀況,或許釋聽任何內部資本(例如圖形句柄、數據庫銜接或文件流),而無需期待運轉時中的渣滓收受接管器終結這些對象。 例如:
static void TestFinally() { System.IO.FileStream file = null; //Change the path to something that works on your machine. System.IO.FileInfo fileInfo = new System.IO.FileInfo(@"C:\file.txt"); try { file = fileInfo.OpenWrite(); file.WriteByte(0xF); } finally { // Closing the file allows you to reopen it immediately - otherwise IOException is thrown. if (file != null) { file.Close(); } } try { file = fileInfo.OpenWrite(); System.Console.WriteLine("OpenWrite() succeeded"); } catch (System.IO.IOException) { System.Console.WriteLine("OpenWrite() failed"); } }
假如 WriteByte() 激發了異常,那末在沒有挪用 file.Close() 的情形下,第二個 try 塊中測驗考試從新翻開文件的代碼就會掉敗,而且文件將堅持鎖定狀況。 因為要履行 finally 塊(即便已激發異常),前一示例中的 finally 塊使得可以准確地封閉文件,從而贊助防止毛病。
假如在激發異常以後沒有在挪用客棧上找到兼容的 catch 塊,則會湧現三種情形中的一種:
假如異常湧現在析構函數中,則中斷該析構函數並挪用基析構函數(假如有)。
假如挪用客棧包括靜態結構函數或靜態字段初始值設定項,則激發一個 TypeInitializationException,並將原始異常分派給新異常的 InnerException 屬性。
假如達到線程的開首,則終止線程。