开发者

What's the difference between various try-catch in C#? [duplicate]

This question already has answers here: Closed 11 years ago.

Possible Duplicate:

the difference between try/catch/throw and try/catch(e)/throw e

Pardon my stupidity, anyone knows difference between them?

 try
 {
      return 1 / 0;
 }
 catch (Exception)
 {
   开发者_开发百科   throw;
 }

 try
 {
      return 1 / 0;
 }
 catch
 {
      throw;
 }

 try
 {
      return 1 / 0;
 }
 catch (Exception e)
 {
      throw(e);
 }


  1. Will catch and rethrow only exceptions derived from Exception.
  2. Will catch and rethrow any exception. (Edit: Since CLRv2, all exceptions are derived from Exception so this is identical to 1. See Eric Lippert's comment below).
  3. Will catch any exception derived from Exception and throw it again, thus resetting the stack trace of the exception.


A catch clause without arguments can catch any type of exception. This is sometimes referred to as the "general" catch clause. You should probably never use this in a production application, but I suppose it might sometimes be useful for debugging. It looks like this:

catch
{
}

A catch clause can also specify the particular exception class that you want to catch. You should always do this in your applications because you're only supposed to catch exceptions that you know how to handle. For example, you might want to catch a DivideByZeroException; you'd do it like this:

catch (DivideByZeroException)
{
}

Of course, that has the side effect that you're unable to refer to the exception class itself inside of the catch block because you haven't assigned it to a variable. If you need to call properties or methods on the instance of the exception class that you catch, you'll need to include a named variable in the catch statement. That is probably what you're most used to seeing, and it looks like this:

catch (DivideByZeroException ex)
{
    // do something with ex here
}

Then there are two ways to write the throw() statement, and it matters which one you choose:

  1. The first just looks like this:

    throw;
    

    It is written without any arguments, and the purpose is to rethrow the caught exception while preserving the stack trace and as much information about the original exception as possible.
    (There are still some edge cases where this can cause you to lose the stack trace, but generally this is much preferred over the alternative below.)

  2. The second option passes an instance of an exception class as an argument, and looks like this:

    throw(ex);
    

    or this:

    throw ex;
    

    This also rethrows the specified exception, but as mentioned above, it has the downside of losing some of the stack trace information that tells you what method was responsible for throwing the exception. It's rare that you'll use this except to throw a new exception object that you create in the same method.

    For example, if you wanted to catch a low-level exception and wrap it within a new exception object for consumption by a higher-level function, you would use this form.


The first two are equivalent.

The third one should generally be avoided: it rethrows the exception from its own stack frame, losing information about the original frames in the process.


catch (Exception) - Catches anything that derives from Exception class

catch (Exception e) - Catches anything that derives from Exception class and assign it to the variable e, which you can use.

catch - catches anything thrown.


There is no difference between example 1 and 2. Both rethrows the original exception, and both catches the general Exception. You would use example 1 if you wanted to catch a more specific exception, such as DivisionByZeroException.

For the last example, you are not re-throwing the exception; but throwing the same exception object that you caught. This causes the exception stacktrace to be re-set to the location where you throw it - which might be a problem because the stacktrace then does not point to the location in code, where the error actually occured.


The difference is that throw e; will throw an exception with a different stack trace. See this accepted answer.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜