C#中的異常處理問題try catch finally
C#中的異常處理是一種檢測和處理代碼中運行時錯誤的機制,由try catch和finaly塊提供支持。
.NET框架提供了常見異常的內(nèi)置類。
程序執(zhí)行期間發(fā)生的異常,它們可能是由于邏輯或系統(tǒng)錯誤引起的。
如果程序員未提供處理這些異常的機制,則.NET運行時環(huán)境將提供默認(rèn)機制,該機制將終止程序執(zhí)行。
try..catch..finally
C#提供了三個關(guān)鍵字try,catch和finally,以實現(xiàn)異常處理。
嘗試將可能引發(fā)異常的語句括起來,而如果存在則catch會處理異常。
finally 可以用于完成任何需要清理的工作。
try..catch..finally塊示例:
try
{
//可能導(dǎo)致異常的語句
}
catch(Type x)
{
//處理異常的語句
}
finally
{
//任何清理代碼
}如果try塊內(nèi)部發(fā)生任何異常,則控制權(quán)轉(zhuǎn)移到適當(dāng)?shù)腸atch塊,然后轉(zhuǎn)移到finally塊。
但是在C#中,catch和finally塊都是可選的。
try塊可以與一個或多個catch塊或finally塊一起存在,也可以與catch和finally塊一起存在。
如果try塊內(nèi)沒有發(fā)生異常,則控件直接轉(zhuǎn)移到finally塊??梢哉f,finally塊中的語句總是執(zhí)行的。
請注意,通過使用break,continue,return或goto將控制權(quán)從finally塊中移出是錯誤的。
在C#中,異常不過是Exception類型的對象。Exception 是C#中任何異常的最終基類。
C#本身提供了幾個標(biāo)準(zhǔn)異常。甚至用戶也可以創(chuàng)建自己的異常類,前提是該異常類應(yīng)繼承自Exception類或Exception類的標(biāo)準(zhǔn)派生類之一,例如DivideByZeroExcpetion到ArgumentException等。
未捕獲的異常
以下程序可以通過編譯,但在執(zhí)行過程中將出現(xiàn)錯誤。
一個數(shù)除零是運行時異常,程序終止并顯示錯誤消息。
當(dāng)前上下文中任何未捕獲的異常都會傳播到更高的上下文,并尋找適當(dāng)?shù)腸atch塊來處理它。
如果找不到任何合適的catch塊,.NET運行時的默認(rèn)機制將終止整個程序的執(zhí)行。
using System;
class MyException
{
public static void Main()
{
int x = 0;
int div = 100/x;
Console.WriteLine(div);
}
}
具有異常處理機制的上述程序的修改形式如下:
在這里,我們使用標(biāo)準(zhǔn)異常類DivideByZeroException的對象來處理由除零引起的異常。
using System;
class MyException
{
public static void Main()
{
int x = 0;
int div = 0;
try
{
div = 100 / x;
Console.WriteLine("此行未執(zhí)行");
}
catch (DivideByZeroException)
{
Console.WriteLine("發(fā)生異常");
}
Console.WriteLine($"結(jié)果為 {div}");
}
} 以上代碼的結(jié)果如下所示:

在上述情況下,程序不會意外終止。
程序控制從try塊內(nèi)發(fā)生異常的地方轉(zhuǎn)移到catch塊,如果找到任何合適的catch塊,則在該catch中執(zhí)行語句,然后繼續(xù)正常執(zhí)行程序語句。
如果存在以下代碼的finally塊,則finally塊中的代碼也將被執(zhí)行。
using System;
class MyException
{
public static void Main()
{
int x = 0;
int div = 0;
try
{
div = 100/x;
Console.WriteLine("此行未執(zhí)行");
}
catch(DivideByZeroException)
{
Console.WriteLine("發(fā)生異常");
}
finally
{
Console.WriteLine("Finally塊");
}
Console.WriteLine($"結(jié)果為 {div}");
}
}
請記住,在C#中,catch塊是可選的。
以下程序在C#中是完全合法的。
using System;
class MyException
{
public static void Main()
{
int x = 0;
int div = 0;
try
{
div = 100/x;
Console.WriteLine("此行未執(zhí)行");
}
finally
{
Console.WriteLine("Finally塊");
}
Console.WriteLine($"結(jié)果為 {div}");
}
}
但是在這種情況下,由于沒有異常處理catch塊,因此執(zhí)行將終止。
但是在終止程序語句之前,finally塊中的語句將得到執(zhí)行。
在C#中,try塊之后必須是catch或finally塊。
多個catch塊
一個try塊可以引發(fā)多個異常,可以使用多個catch塊來處理。
記住,在通用的catch 塊之前應(yīng)該有更專業(yè)的catch 塊。否則,編譯器將顯示編譯錯誤。
using System;
class MyException
{
public static void Main()
{
int x = 0;
int div = 0;
try
{
div = 100 / x;
Console.WriteLine("此行未執(zhí)行");
}
catch (DivideByZeroException de)
{
Console.WriteLine("DivideByZeroException");
}
catch (Exception)
{
Console.WriteLine("Exception");
}
finally
{
Console.WriteLine("Finally塊");
}
Console.WriteLine($"結(jié)果為 {div}");
}
}捕獲所有異常
通過提供沒有方括號或參數(shù)的catch塊,我們可以捕獲try塊內(nèi)發(fā)生的所有異常。
即使我們可以使用帶有Exception類型參數(shù)的catch塊來捕獲try塊內(nèi)發(fā)生的所有異常,因為在C#中,所有異常都直接或間接地從Exception類繼承。
using System;
class MyException
{
public static void Main()
{
int x = 0;
int div = 0;
try
{
div = 100 / x;
Console.WriteLine("此行未執(zhí)行");
}
catch
{
Console.WriteLine("oException");
}
Console.WriteLine($"結(jié)果為 {div}");
}
}以下程序使用Exception對象處理所有異常。
using System;
class MyException
{
public static void Main()
{
int x = 0;
int div = 0;
try
{
div = 100 / x;
Console.WriteLine("此行未執(zhí)行");
}
catch (Exception)
{
Console.WriteLine("oException");
}
Console.WriteLine($"結(jié)果為 {div}");
}
}引發(fā)異常
在C#中,可以以編程方式引發(fā)異常。為此,使用了“ throw”關(guān)鍵字。引發(fā)異常的一般形式如下。
throw exception_obj;
例如,以下語句顯式引發(fā)ArgumentException。
throw new ArgumentException("Exception");
using System;
class MyException
{
public static void Main()
{
try
{
throw new DivideByZeroException("Invalid Division");
}
catch (DivideByZeroException)
{
Console.WriteLine("Exception");
}
Console.WriteLine("LAST STATEMENT");
}
}重新拋出異常(throw)
我們在catch塊內(nèi)捕獲的異??梢酝ㄟ^使用catch塊內(nèi)的關(guān)鍵字throw來重新拋出更高的上下文。
以下程序顯示了如何執(zhí)行此操作。
//C#: Exception Handling: Handling all exceptions
using System;
class MyClass
{
public void Method()
{
try
{
int x = 0;
int sum = 100 / x;
}
catch (DivideByZeroException)
{
throw;
}
}
}
class MyException
{
public static void Main()
{
MyClass mc = new MyClass();
try
{
mc.Method();
}
catch (Exception)
{
Console.WriteLine("此處捕獲異常");
}
Console.WriteLine("LAST STATEMENT");
}
}標(biāo)準(zhǔn)例外
異常有兩種類型:由執(zhí)行程序生成的異常和由公共語言運行時生成的異常。
System.Exception是C#中所有異常的基類。多個異常類從該類繼承,包括ApplicationException和SystemException。
這兩個類構(gòu)成了大多數(shù)其他運行時異常的基礎(chǔ)。直接從System.Exception派生的其他異常包括IOException,WebException等。
公共語言運行庫引發(fā)SystemException。ApplicationException由用戶程序而不是運行時引發(fā)。
SystemException包括ExecutionEngineException,StaclOverFlowException等。
不建議我們捕獲SystemException,也不建議在我們的應(yīng)用程序中拋出SystemException。
- System.OutOfMemoryException
- System.NullReferenceException
- Syste.InvalidCastException
- Syste.ArrayTypeMismatchException
- System.IndexOutOfRangeException
- System.ArithmeticException
- System.DevideByZeroException
- System.OverFlowException
用戶定義的異常
在C#中,可以創(chuàng)建我們自己的異常類。但是Exception必須是C#中所有異常的最終基類。
因此,用戶定義的異常類必須從Exception類或其標(biāo)準(zhǔn)派生類之一繼承。
using System;
//用戶自定義的異常
class CustomException : Exception
{
public CustomException(string str)
{
Console.WriteLine("用戶定義的異常");
}
}
class MyException
{
public static void Main()
{
try
{
throw new CustomException("RAJESH");
}
catch (Exception e)
{
Console.WriteLine("此處捕獲異常" + e.ToString());
}
Console.WriteLine("LAST STATEMENT");
}
}設(shè)計準(zhǔn)則
異常應(yīng)用于傳達特殊情況。不要使用它們來傳達預(yù)期的事件,例如到達文件末尾。
如果在System命名空間中有一個很好的預(yù)定義異常,它描述了異常情況——一個對類的用戶有意義的——使用該類而不是定義一個新的異常類,并在消息中放入特定的信息。
最后,如果代碼捕獲到了將要處理的異常,請在重新拋出該異常之前考慮是否應(yīng)將異常與其他信息一起包裝。
try中的return語句先于finally中的函數(shù)執(zhí)行
代碼如下:
static void Main(string[] args)
{
Console.WriteLine(GetNum());
}
public static int GetNum()
{
int Num=1;
try
{
Console.WriteLine("try");
return Num;
}
catch (Exception ex)
{
throw ex;
}
finally
{
++Num;
Console.WriteLine("finally");
}
}輸出結(jié)果如下:

結(jié)論
try中的return語句先于finally中的函數(shù)執(zhí)行所以,返回的結(jié)果是1, 而不是2。
從運行結(jié)果可以看出,return語句執(zhí)行后,將把返回結(jié)果放置進函數(shù)棧中,此時函數(shù)并不是馬上返回,它要執(zhí)行finally語句后才真正開始返回。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
C#中Dictionary<TKey,TValue>排序方式的實現(xiàn)
這篇文章主要介紹了C#中Dictionary<TKey,TValue>排序方式的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
C#將隱私信息(銀行賬戶,身份證號碼)中間部分特殊字符替換成*
大家在銀行交易某些業(yè)務(wù)時,都可以看到無論是身份證、銀行賬號中間部分都是用*號替換的,下面這篇文章主要介紹C#將隱私信息(銀行賬戶,身份證號碼)中間部分特殊字符替換成*的相關(guān)資料,需要的朋友可以參考下2015-08-08

