1

Here are two previous questions regarding this topic:

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 significantly) 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) { } 
3
  • Could the downvoters say why they downvoted this question? Commented Oct 7, 2009 at 20:15
  • 1
    The only question is "Anyone have any opinions about it?". The answer is: "yes, most of us are very opinionated people." Either ask a "real" question, or GTFO. Commented Oct 14, 2009 at 21:49
  • Another kind, functional style: well, quite not as clean (as your and many other suggestion here), but this works. Commented May 18, 2013 at 11:17

7 Answers 7

3

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.

Sign up to request clarification or add additional context in comments.

6 Comments

I like this approach as it mimicks how to stack case statements. As long as the coder is willing to determine the type in the catch block as needed.
Check my two edits, plus this doesn't address the issue of what type e is.
I think this would work, but the variable names on the parameters should probably be unique.
@Jon then @Joel: Then you end up checking each one for null. With mine, you can use the code without checks/casts since you know e is a non-null value of type ArgumentException. This is a massive difference in terms of code clarity. Also, note that my catch block doesn't handle exceptions of the more general type ArgumentException, it just declares e as that type since ArgumentNullException and ArgumentOutOfRangeException both cast to that.
@280Z28: In this case, the last catch line would be required to be a base type that is a parent of all previous types.
|
1

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.)

1 Comment

That proposal is poorly defined because it doesn't address the primary issue of giving a staticly valid type to the variable e. The list of handled exceptions (separated in my post by , and in the Java proposal by |) should be separate from the exception variable declaration type. Mine uses as to clearly separate the two. The Java proposal could use as, or maybe catch (InstantiationException | IllegalAccessException : VariableType e) with the requirement that each type in the exception list be castable to VariableType.
0

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.

3 Comments

That's a workaround for the lack of this feature, and it's specifically discussed in the links I added. I added the Edit 2 above to address one major benefit of adding language syntax for this use case.
Wokrarounds work NOW, how long are you going to wait for a language feature to be added? Assuming it will EVER happen?
But that's not the point of this question. I already know how to handle the situation with what's available. Languages evolve over time, taking on characteristics of what people come up with. This will probably never happen (there is a very low statistical rate of feature acceptance), but at least to me it's something to think about. :)
0

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 } 

1 Comment

This is for cases where most or all of the code in the catch block is shared for each of the handled exception types.
0

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 :)

4 Comments

This doesn't handle all ArgumentExceptions, only the two listed. the as ArgumentException e gives e a type that's guaranteed to be compatible with every possible exception this catch block is declared to handle.
Did you edit the question, or did I just miss it? I could have sworn it just listed the three exceptions before. Ah well - editing :)
I didn't edit the code, but I added the two marked paragraphs explaining why this might be better than current. There are some APIs (is it ASP.NET?) that require exception handling for many different types of exceptions and I've seen the code get very, very redundant with no simple way to improve it.
That's only going to be if you either want to handle or wrap the exception though - I usually just let the exception propagate.
0

you can try this

try { // do something.... } catch(Exception ex) { if(ex is ArgumentException || ex is FormatException) { //do something } else { throw; } } 

Or even simpler

try { // do somthing. } catch (Exception ex) when (ex is FormatException || ex is OverflowException) { //do something } catch(Exception ex) { throw ex; } 

Comments

-1

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

1 Comment

e is obviously an ArgumentException, since as I said its type must be a base type of or interface of every listed handled exception. The catch block will not handle any ArgumentException other than ArgumentNullException and ArgumentOutOfRangeException. I actually asked this question specifically because this syntax solved the problem you mention.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.