2

Is possible to catch more then one exception in the same catch block?

try
{   }
catch(XamlException s | ArgumentException a)
{   }
gliderkite
  • 8,828
  • 6
  • 44
  • 80
  • 2
    http://stackoverflow.com/questions/136035/catch-multiple-exceptions-at-once – Bali C Jun 26 '12 at 16:15
  • That syntax is not part of the C# standard so you will end up with compiler errors :) – t0mm13b Jun 26 '12 at 16:16
  • While this may not be actual code you're showing us, `ArgumentException` derives from `SystemException`, so `catch (SystemException)` is enough to ensnare both types. Of course you'd still need to cast if you wanted to inspect the argument that was incorrect, but if you need that much information, a separate `catch` block probably makes more sense anyway. Finally, you should really never be catching `ArgumentException` anyway; it means you've done something wrong, so just fix the problem rather than ignoring it. – dlev Jun 26 '12 at 16:19
  • http://blogs.msdn.com/b/toub/archive/2004/03/05/84698.aspx, to handle filters and multiple exceptions. Even if VB.NET/F# allow something like that it's a kind of trick because it's not supported directly by the CLR. – Adriano Repetti Jun 26 '12 at 16:21

5 Answers5

7

Yes. If you catch a superclass, it will also catch all subclasses too:

try
{
    // Some code
}
catch(Exception e)
{
    // ...
}

If this catches more than you wanted then you can rethrow the exceptions that you didn't intend to catch by testing their type. If you do this, be careful to use the throw; syntax, and not throw e;. The latter syntax clobbers the stacktrace information.

But you can't catch two different types using the syntax you propose.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • 1
    Good point on specifying between `throw;` and `throw e;`. Just to further clarify, the reason the latter is bad is because it resets the call stack to originate from the catch block rather than from where the exception was initially thrown. I'm sure you knew this, I just wanted to clarify for others :) – Devin Jun 26 '12 at 16:19
  • Even **throw e;** does not really work as expected. It saves the stack but it wipes the line number. For an example look [this answer](http://stackoverflow.com/questions/10721807/using-finally-instead-of-catch/10722087#10722087) I posted here on SO. – Adriano Repetti Jun 26 '12 at 16:28
  • @Adriano: Did you mean "Even `throw;`"? – Mark Byers Jun 26 '12 at 16:30
3

Not as succinctly as you are asking. One way would be to catch all exceptions and handle those two specially:

catch(Exception e)
{   
  if((e is SystemException) || (e is ArgumentException))
     // handle, rethrow, etc.
  else
     throw;
}
D Stanley
  • 149,601
  • 11
  • 178
  • 240
2

Not being no C# guru however, this is standard in any oop language.

    try
    {
        string s = null;
        ProcessString(s);
    }
    // Most specific:
    catch (InvalidCastException e) { out_one(e); }
    catch (ArgumentNullException e) { out_two(e); }

    // Least specific - anything will get caught
    // here as all exceptions derive from this superclass
    catch (Exception e)
    {
        // performance-wise, this would be better off positioned as
        // a catch block of its own, calling a function (not forking an if)
        if((e is SystemException) { out_two(); }
        else { System..... }
    }
mschr
  • 8,531
  • 3
  • 21
  • 35
1

In vb.net, it is possible to say Catch Ex As Exception When IsMyException(Ex), where IsMyException is any desired function which examines Ex and decides whether or not to catch it. The determination of whether or not to catch Ex is made before any inner Finally blocks run. Unfortunately, the makers of C# dislike the idea of allowing custom exception filters, perhaps because it would pollute the language with platform-specific details (most platforms could not support .net-style exception filters). Consequently, the best one can hope for in C# is to do something like:

void HandleThisOrThatException(BaseTypeOfThisThatTheOtherException)
{ ... }

...
// Catch ThisException or ThatException, but not TheOtherException
  catch (ThisException ex) {HandleThisOrThatException(ex);}
  catch (ThatException ex) {HandleThisOrThatException(ex);}
supercat
  • 77,689
  • 9
  • 166
  • 211
0

It's a bad example because any ArgumentException is also a SystemException, so catching all SystemExceptions would implicitly get the ArgumentExceptions as well.

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
  • 2
    The point of catching a specific exception before the superclass exception is, you have a higher level of control. Above sample is randomly copied exception names tbh, OP asks for semantics. – mschr Jun 26 '12 at 18:52