views:

122

answers:

3

Hi

I want to merge the catch blocks in the following code for code reuse reasons:

try
{
    DoSomeInputOutput();
}
catch (InvalidOperationException ex)
{
    HandleKnownException1(ex);
}
catch (InvalidDataException ex)
{
    HandleKnownException1(ex);
}
catch (ArgumentNullException ex)
{
    HandleKnownException1(ex);
}
catch (ArgumentOutOfRangeException ex)
{
    HandleKnownException2(ex);
}
catch (ArithmeticException ex)
{
    HandleKnownException2(ex);
}
catch (InvalidCastException ex)
{
    HandleKnownException2(ex);
}
catch (Exception ex)
{
    HandleUnknownException(ex);
}

to something like this:

try
{
    DoSomeInputOutput();
}
catch (InvalidOperationException ex)
catch (InvalidDataException ex)
catch (ArgumentNullException ex)
{
    HandleKnownException1(ex);
}
catch (ArgumentOutOfRangeException ex)
catch (ArithmeticException ex)
catch (InvalidCastException ex)
{
    HandleKnownException2(ex);
}
catch (Exception ex)
{
    HandleUnknownException(ex);
}

Is that possible somehow?

Thanks.

+3  A: 

No (or at least: not unless the exceptions you want to group happen to share a common base-class specific to that group, which they don't in your example); the only thing you can do in this scenario is catch (Exception ex) and do runtime testing on ex. By the time you've done that, I expect your code is already "prettier" as-is (since, importantly, you've already refactored the handling code into a method).

I'd be tempted to tweak the spacing so I can focus on the important code:

try
{
    DoSomeInputOutput();
}
// blah humorous scenario 1
catch (InvalidOperationException ex) { HandleKnownException1(ex); }
catch (InvalidDataException ex) { HandleKnownException1(ex); }
catch (ArgumentNullException ex) { HandleKnownException1(ex); }
// blah whimsical scenario 2
catch (ArgumentOutOfRangeException ex) { HandleKnownException2(ex); }
catch (ArithmeticException ex) { HandleKnownException2(ex); }
catch (InvalidCastException ex) { HandleKnownException2(ex); }
// unexpected comedy
catch (Exception ex) { HandleUnknownException(ex); }

(or something).

In some ways this also ties into this question: switch / pattern matching idea.

Marc Gravell
+1  A: 

You could only do something like this if you had a decent hierarchy of exceptions, then you could catch a an exception of a type higher up in the hierarchy. However, exception hierarchies are meant to be pretty shallow by design and there is no guarantee that you would want to handle the exceptions the same way based solely on the hierarchy. And besides... none of that would help with standard exception types used in your example.

Leigh Shayler
+4  A: 

Presumably, you do it in more than one place. If so, why don't you do this:

{
    DoSomeInputOutput();
}
catch (Exception ex)
{
    HandleInputException(ex);
}

void HandleInputException(Exception ex)
{
   if (ex is InvalidOperationException || ex is InvalidDataException || ex is ArgumentNullException)
   {
     HandleKnownException1 (ex);
   }
   else if ...
   else if ...
}
yu_sha