开发者

Possible syntax for multi-type catch blocks in C#?

Here are two previous questions regarding this topic:

  • Catch multiple Exceptions at once?
  • More Elegant Exception Handling Than Multiple Catch Blocks?

I was working today and thought this might be an appropriate syntax should this feature ever be added to the C# language. Anyone have any opinions about it?

The type of e must be a base type or interface of every exception type listed.

Edit: In this example, the catch block handles either ArgumentNullException or ArgumentOutOfRangeException and places the exception instance in a variable of type ArgumentException called e. It doesn't handle any other type of ArgumentException other than the two listed. I think there was some confusion about the associativity of the , and the as.

Edit 2: If the listed exceptions all upcast to a variable of the type of e, then the code compiles cleanly to MSIL without any casts or explicit type checks, making it faster (potentially significa开发者_Python百科ntly) than the current syntax of catching ArgumentException followed by a throw; if it's not one of the two you intended. The problem is even more obvious if you're catching Exception and checking for two possible types to handle and rethrowing if it's something else.

try
{
}
catch (ArgumentNullException, ArgumentOutOfRangeException as ArgumentException e)
{
}


See this:
Cool or Stupid? Catch(Exception[NamingException, CreateException] e)

My answer to that question is that they should let you "stack" them like with using blocks:

try
{
}
catch (ArgumentNullException e)
catch (ArgumentOutOfRangeException e)
catch (ArgumentException e)
{

}

Though I see you're going for and rather than or . Personally I don't see the and approach as very useful, because you're already constrained to a real non-interface exception type and there's no dual-inheritance.


Inclusion of this feature is planned for Java 7 with the following syntax:

try {  
    return klass.newInstance();  
} catch (InstantiationException | IllegalAccessException e) {  
    throw new AssertionError(e);  
}

Edit: I think the intention is for the static type of e to be the most specific common superclass of the listed exceptions. (In Java, only instances of class java.lang.Throwable can be thrown, hence catching with a common super interface is of limited utility since the exception can not be re-thrown.)


You can already do this, just

 try{}
 catch(Exception e)
 {}

since all exceptions derive from System.Exception. And you would do just as you would above, determine the type of the exception in the catch block itself.


If ArgumentNullException and ArgumentOutOfRangeException have different interfaces, will be a pain to cast correctly;

For instance ArgumentOutOfRangeException have an ActualValue property; if you had to use it, you'll end with something like:


if(e is ArgumentOutOfRangeException)
{
    // use e.ActualValue
}
else
{
    // use e.Data
}


I don't find myself wanting this very often in C#, whereas in Java I find there are various situations where I have to catch a bunch of checked exceptions and wrap them all in a different exception that my method is declared to throw.

That's something I'd possibly like some syntax for:

try
{
}
wrap (OneException as AnotherException)
catch (HandleableException e)
{
    // Actual handling for some exception types
}

... but again, I find myself doing that much more in Java than in C#.

There are other enhancements which are way higher up my list for C# than this :)


That would only work if you do not declare an instance (e). If you reference the e inside the block, what is it?

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜