新手经常区分不清楚throw 跟 throw ex 有什么区别,在一些遗留代码中我们也经常能见到类似的错误用法。
一句话总结:throw ex 会重置调用栈,而throw不会。绝大多数情况我们都不希望调用栈被重置,这样不利于定位问题。
下面做一个简单的测试:
1 namespace SimpleConsole 2 { 3 internal class ExceptionTest 4 { 5 public void Test() 6 { 7 try 8 { 9 Method1(); 10 } 11 catch (Exception ex) 12 { 13 Console.WriteLine(ex.Message); 14 Console.WriteLine(ex.StackTrace); 15 } 16 17 Console.WriteLine("#################################################"); 18 19 try 20 { 21 Method2(); 22 } 23 catch (Exception ex) 24 { 25 Console.WriteLine(ex.Message); 26 Console.WriteLine(ex.StackTrace); 27 } 28 } 29 30 public void Method1() 31 { 32 try 33 { 34 ThrowException("Method 1"); 35 } 36 catch (Exception ex) 37 { 38 throw ex; 39 } 40 } 41 42 public void Method2() 43 { 44 try 45 { 46 ThrowException("Method 2"); 47 } 48 catch (Exception ex) 49 { 50 throw; 51 } 52 } 53 54 private void ThrowException(string msg) 55 { 56 throw new Exception("Exception from " + msg); 57 } 58 } 59 }
输出:
可以看到,Method1中捕获到的异常我们只能看到它是从throw ex 位置抛出来的,并不知道具体是由哪个调用抛出的。但是Method2方法能明显看到是由ThrowException 这个方法抛出来的,当调用栈比较复杂的时候,Method1中的写法可能会导致很难定位问题。