Throw會拋出/傳遞異常,通過在catch塊里使用throw語句.可以改變產生的異常,比如我們可以拋出一個新的異常,throw語句有各種各樣的,並且很有必要.
例子
我們首先看一下三個方法,分別叫做A,B,C,他們使用不同的throw語句。方法A使用了無參的throw語句。這可以被看作是rethrow(繼續拋出)—他會拋出已經出現的同樣的異常
繼續,方法B throw一個命名的異常變量。這就不是一個完全的rethrow了—因為他雖然拋出了同樣的異常。但是改變了StackTrace(堆棧軌跡),如果有必要的話,我們可以收集一些異常信息,而方法C則創建了一個新的異常。
提示:你可以通過這種方法實現自定義的的錯誤處理
使用throw語句的例子
using System; class Program { static void Main() { try { A(); B(); C(null); } catch (Exception ex) { Console.WriteLine(ex); } } static void A() { // Rethrow 語法. try { int value = 1 / int.Parse("0"); } catch { throw; } } static void B() { // 過濾異常類型. try { int value = 1 / int.Parse("0"); } catch (DivideByZeroException ex) { throw ex; } } static void C(string value) { // 創建新的異常. if (value == null) { throw new ArgumentNullException("value"); } } }
程序可能的輸出結果
System.DivideByZeroException: Attempted to divide by zero. System.DivideByZeroException: Attempted to divide by zero. System.ArgumentNullException: Value cannot be null. Parameter name: value
Rethrow
接着我們看更多的關於rethrows的細節。Rethrow必須是一個無參的throw語句。如果使用throw ex,那么TargetSie(TargetSite 從堆棧跟蹤中獲取拋出該異常的方法。如果堆棧跟蹤為空引用,TargetSite 也返回空引用。-譯者注)和StackTrace都被改變了。
在下面的程序里,X()方法使用了rethrow語句。Y()使用了throw ex語句。我們可以看看當rethrow語句使用的使用,引發異常的方法,也就是異常的TargetSite是在StringToNumber---一個int.Parse內部的方法。
但是:當throw ex用的時候。就像在Y()里面,這個異常的TargetSite被修改到了當前的Y()方法里。
測試rethrow的例子
using System; class Program { static void Main() { try { X(); } catch (Exception ex) { Console.WriteLine(ex.TargetSite); } try { Y(); } catch (Exception ex) { Console.WriteLine(ex.TargetSite); } } static void X() { try { int.Parse("?"); } catch (Exception) { throw; // [Rethrow 構造] } } static void Y() { try { int.Parse("?"); } catch (Exception ex) { throw ex; // [Throw 捕獲的ex變量] } } }
輸出
Void StringToNumber(System.String, ...)
Void Y()
總結:
異常處理機制提供了可選的控制路徑,它將異常邏輯和異常處理分割開來。並且可以通過throw來rethrow異常或是生成一個新的異常。
譯自:http://www.dotnetperls.com/throw
本文由Bystander翻譯,轉載請注明http://leaver.me