如何抛出异常

问题描述:

在和throw ex;之间选择的最佳做法是什么?有没有呢?关于实施例 - - 对于这个简单的代码片段:如何抛出异常

try{ 
    // some code 
} catch (Exception ex) { 
    // some catcher code 
    // throw; ? 
    // or 
    // throw ex; ? 
    // how to decide which one? 
} 

UPDATE: 我知道上面的拖车之间的差异。问题是如何决定使用其中之一?有没有最好的做法来做出更好的选择?

+2

使用'throw',这会保留原始堆栈跟踪。但为什么你会发现一个普遍的例外呢?在我看来,你无法处理它,为什么要抓住它? – Maarten

+0

@Maarten它有时会发生。重试一些操作,例如 –

+0

[有没有区别“throw”和“throw ex”?](http://stackoverflow.com/questions/730250/is-there-a-difference-between-throw -and-throw-ex) – Sinatr

这是非常simple

您是否想要保持堆栈跟踪来准确查看发生异常的位置?然后使用throw,这就好比你根本不使用catch

你只关心当前方法调试信息?然后throw ex

为了证明:

static void Main(string[] args) 
{ 
    try 
    { 
     Test(); 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e); 
    } 
} 

static void Test() 
{ 
    try 
    { 
     // long lambda chain 
     new Action(() => new Action(() => new Action(() => { throw new InvalidOperationException(); })())())(); 
    } 
    catch (Exception ex) 
    { 
     //throw; 
     //throw ex; 
    } 
} 

throw将保持堆栈跟踪:

System.InvalidOperationException: Operation is not valid due to the current state of the object. 
    at ConsoleApplication.Program.<>c.<Test>b__1_2() in ConsoleApplication\Program.cs:line 22 
    at ConsoleApplication.Program.<>c.<Test>b__1_1() in ConsoleApplication\Program.cs:line 22 
    at ConsoleApplication.Program.<>c.<Test>b__1_0() in ConsoleApplication\Program.cs:line 22 
    at ConsoleApplication.Program.Test() in ConsoleApplication\Program.cs:line 26 
    at ConsoleApplication.Program.Main(String[] args) in ConsoleApplication\Program.cs:line 13 

throw ex将重置堆栈跟踪:

System.InvalidOperationException: Operation is not valid due to the current state of the object. 
    at ConsoleApplication.Program.Test() in ConsoleApplication\Program.cs:line 27 
    at ConsoleApplication.Program.Main(String[] args) in ConsoleApplication\Program.cs:line 13 

至于最佳实践 - 的选择通常为throw,作为开发者,你想获得尽可能多的信息,throw ex是一个对应的 - 一些信息是隐藏的,但也许你想隐藏它,谁知道?

您应该使用throw;重新抛出原始异常(与原来的堆栈跟踪),或使用throw new MyException(..., ex);抛出自己的异常,可能提供额外的信息,并设置内部异常能恩。

如果你没有任何额外的信息只是用throw;

如果只捕捉到了异常做清理,然后用try {...} finally {...}代替。