The diff between throw and throw e
Today, in the interview,this question be asked, but I cant't answer because I am cpluspluser before, I turn to learn C# not long.
So, what the different between throw and throw e? I found a amasing answer here when I search some information with google.
I run the program in vs2008, the code is :
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace DiffBetweenThrowAndThrowE 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 try 13 { 14 ThrowException1(); // line 14 15 } 16 catch (Exception x) 17 { 18 Console.WriteLine("Exception 1:"); 19 Console.WriteLine(x.StackTrace); 20 } 21 22 try 23 { 24 ThrowException2(); // line 24 25 } 26 catch (Exception x) 27 { 28 Console.WriteLine("Exception 2:"); 29 Console.WriteLine(x.StackTrace); 30 } 31 } 32 33 private static void ThrowException1() 34 { 35 try 36 { 37 DivByZero(); // line 37 38 } 39 catch 40 { 41 throw; // line 41 42 } 43 } 44 45 private static void ThrowException2() 46 { 47 try 48 { 49 DivByZero(); // line 49 50 } 51 catch (Exception ex) 52 { 53 throw ex; // line 53 54 } 55 } 56 57 private static void DivByZero() 58 { 59 int x = 0; 60 int y = 1 / x; // line 60 61 } 62 } 63 }
The resualt of the program is:
What's the same:
- Both throw an exception.
- Both have the same debuggability problems associated with catch / rethrow.
- They can be called in the same way. I used code like:
catch (Exception e) { if (...) throw; else throw e;
as an academic way to demonstrate that they must have some similar properties. Never actually write code like that!
- They can both be used in a naked catch block, although as difference #1 below mentions, 'throw e'; can't be used to rethrow the current exception.
catch { thrownew MyWrapperException(); }
What's different:
- 'throw;' can only be used in the lexical scope of a catch block since it must gaurantee having a current exception. 'throw e' can be used anywhere.
- 'throw e' lets you provide a new exception object, such as a wrapper around the original exception.
- Only 'throw' can be used to rethrow the current exception within a naked catch block
- They both rethrow the current exception object, but “throw e;” resets parameters on it like the Exception.StackWalk property.
- They generate different IL opcodes. C#'s 'throw;' compiles to the 'rethrow' IL opcode, which doesn't take any parameters on the IL stack. 'throw e;' compiles to the 'throw' IL opcode, which takes 1 IL stack parameter: the exception to throw.
中文意思:
1.throw: CLR会保留原始的异常栈信息。这样方便调试很容易找到出错的行号
2. throw e: CLR也会保留异常信息,但会修改异常堆栈信息,所以StackTrace异常的行不是try里的实现出错行,而是throw e 的出错行,这样对于调试为说,有点误导作用,但你可以在throw e的时候将异常的原因写明白一抛出,比如:
try { ... } catch (IOException e) { ... throw new ApplicationException("Some informative error message", e); }
这也是它的优点所在