10

What's the difference between the following catch blocks?

try
{
    ...
}
catch
{
    ...
}

and

try
{
    ...
}
catch(Exception)
{
    ...
}

I realize, in either case, the exception instance is not available but is there anything that I can do with one that is not possible with the other?

David Ferenczy Rogožan
  • 23,966
  • 9
  • 79
  • 68
Bala R
  • 107,317
  • 23
  • 199
  • 210

6 Answers6

7

They are almost the same.

From the C# Language Specification, section 8.10:

Some programming languages may support exceptions that are not representable as an object derived from System.Exception, although such exceptions could never be generated by C# code. A general catch clause may be used to catch such exceptions. Thus, a general catch clause is semantically different from one that specifies the type System.Exception, in that the former may also catch exceptions from other languages.

Note that while C# differentiates between the two, they are effectively the same as of .NET 2.0, as noted by this blog:

Thanks to a recent change in the 2.0 CLR, if you had code that decided to throw, say, an int (System.Int32) somewhere, the CLR will now wrap it with a RuntimeWrappedException, and the compiler has been updated to give you that warning that the second clause above is now dead code

warning CS1058: A previous catch clause already catches all exceptions. All non-exceptions thrown will be wrapped in a System.Runtime.CompilerServices.RuntimeWrappedException

For how the CLR knows to do this action for your assembly, you'll notice the compiler now adds a RuntimeCompatibilityAttribute to your assemblies telling it to:
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = {property bool 'WrapNonExceptionThrows' = bool(true)}

Gabe
  • 84,912
  • 12
  • 139
  • 238
  • +1 Thanks for the reference! but I'm accepting @Joren 's answer because he was the first to point it out. – Bala R Mar 17 '11 at 21:35
  • Ha! It turns out that Joren and I were wrong afterall -- they *are* the same now. – Gabe Sep 13 '11 at 09:04
7

catch without arguments will catch non CLS-compliant exceptions, unlike catch (Exception).

Joren
  • 14,472
  • 3
  • 50
  • 54
  • Could you provide a reference for this statement? – Ray Hayes Mar 17 '11 at 21:29
  • @Ray Hayes: see my answer: http://stackoverflow.com/questions/5345436/net-exception-catch-block/5345456#5345456 – Gabe Mar 17 '11 at 21:31
  • This is true. Non-CLS compliant exceptions are caught by this notation http://msdn.microsoft.com/en-gb/bb264489.aspx – John Leidegren Mar 17 '11 at 21:36
  • Is this a feature or a bug? :) From the descriptions it seems like unwanted functionality. But I assume thats because for the majority of users it wouldn't be helpful? – James Hulse Mar 17 '11 at 22:04
  • 2
    @havok: I guess the purpose of this is so that if you call into a third party library you're not helpless if it happens to throw a non-CLS-compliant exception. – Joren Mar 17 '11 at 23:05
4

From Why catch(Exception)/empty catch is bad

Empty catch statements can be just as bad, depending on the MSIL code that your language generates. C# turns an empty catch statement into catch(System.Object) which means you end up catching all exceptions - even non-CLS compliant exceptions. VB is better-behaved, turning an empty catch statement into catch e as System.Exception which limits you to catching CLS compliant exceptions.

0xced
  • 25,219
  • 10
  • 103
  • 255
alexandrul
  • 12,856
  • 13
  • 72
  • 99
3

If you look at the generated IL here's the difference:

catch(Exception){}:

catch [mscorlib]System.Exception
{}

and just plain catch:

catch{}:

catch [mscorlib]System.Object
{}

So in theory, if you create a language that can have exceptions NOT inherit from System.Exception, there would be a difference...

BFree
  • 102,548
  • 21
  • 159
  • 201
1

Non-CLS adhering languages (like C++/CLI) can throw objects not derived from System.Exception class. The first code sample will allow you to execute code in the catch block, though you can't examine the thrown object itself. This is almost never an issue, but it could be.

Peter Oehlert
  • 16,368
  • 6
  • 44
  • 48
0

I don't believe there is a difference, and a tool like Resharper would tell you that the catch(Exception) is redundant in the second instance, UNLESS you also inserted other catch(SomeSubclassException) exception handling blocks before Exception to apply different exception handling logic for other exception conditions.

James Webster
  • 4,046
  • 29
  • 41