2

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);
 }
Community
  • 1
  • 1
Domi.Zhang
  • 1,675
  • 4
  • 21
  • 27

6 Answers6

4
  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.
Anders Abel
  • 67,989
  • 17
  • 150
  • 217
  • 3
    I believe 1 & 2 to be equivalent, you can't throw anything not deriving from Exception in .C#. – driis Jul 17 '11 at 10:16
  • 2
    @driis: Even if you can't throw them from C#, you can certainly be consuming libraries written in other languages that can and *do* throw other types of exceptions. It's important to have a mechanism to catch them if you need to. – Cody Gray - on strike Jul 17 '11 at 10:22
  • 4
    @Cody: You are reasoning as though this were 2001. Since CLR v2, if an object is thrown that does not derive from Exception, that object is detected and wrapped in a wrapper object that *does* derive from Exception. There are ways of turning that behaviour off if you need to for some weird backwards compatibility scenario, but in practice, no one needs to worry about thrown objects not derived from Exception anymore. See the documentation for RuntimeWrappedException for details. – Eric Lippert Jul 17 '11 at 15:19
  • @Eric: You're right! I had *no* idea that had changed at the level of CLR. Good to know, I just discovered the `RuntimeWrappedException` class. – Cody Gray - on strike Jul 17 '11 at 15:25
2

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.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
1

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.

Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
0

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.

Yochai Timmer
  • 48,127
  • 24
  • 147
  • 185
0

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.

driis
  • 161,458
  • 45
  • 265
  • 341
0

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

Community
  • 1
  • 1
devio
  • 36,858
  • 7
  • 80
  • 143