淡水求咸

博客园已经停止更新,请移步 http://lovecjh.com/

导航

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 }
View Code

  The resualt of the program is:

What's the same:

  1. Both throw an exception.
  2. Both have the same debuggability problems associated with catch / rethrow.
  3. 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!

  4. 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:

  1. '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.
  2. 'throw e' lets you provide a new exception object, such as a wrapper around the original exception.
  3. Only 'throw' can be used to rethrow the current exception within a naked catch block
  4. They both rethrow the current exception object, but “throw e;” resets parameters on it like the Exception.StackWalk property.
  5. 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);
}

这也是它的优点所在

  

posted on 2013-06-04 18:58  深圳彦祖  阅读(284)  评论(0编辑  收藏  举报