C#net 2

You might also like

Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 2

enhancements (generics, partial classes, etc), but items that would either cause compile

errors, create warnings, or change (presumably improve) behavior. I haven’t seen much
of a comprehensive listing of these changes so I decided to try my hand at coming up
with one. In today’s post I am going to talk about a change in exception handling.
Consider the following code listing:

In C# 1.0, this code was perfectly valid.


However, in C# 2.0 it results in a
warning. Why is that?
An empty catch block(catch{ … }),
compiles down to CIL code that is the
equivalent of catch(object ){ … }. In
other words, an empty catch block in C#
is a catch block for any and all types that
are thrown as exceptions. (Interestingly,
C# doesn’t allow you to explicitly code
catch(object ){ … }. Therefore, there is no means of catching a non-System.Exception-
derived exception and have the exception instance to scrutinize.)
It is perhaps surprising that catch(object ){ … } is needed because C# doesn’t allow you
to throw an exception that doesn’t derive from System.Exception. However, the same
restriction does not apply to other languages. C++, for example, can throw an object of
any type (whether derived from System.Exception or not). As a result, in C# 1.0, the only
way to ensure that all exceptions were caught was to include an empty catch block.
In C# 2.0 the rules improved. Although it is still possible for other languages to throw
exceptions of any type, the CLR will wrap all exceptions that do not derive from
System.Exception into an exception of this type:
Sys tem.Runt ime .Comp i le r
Services.RuntimeWrappedException
This exception does derive from System.Exception. In other words, all exceptions,
whether System.Exception-derived or not when they are thrown, will be caught in C#
2.0 code by acatch(Exception ){ … } block.
Therefore, if you follow acatch(Exception ){ … } block by an empty exception block (as
shown in the initial code listing), the empty exception block will never execute. All
exceptions will be wrapped in the RuntimeWrappedException if they do not derive
from System.Exception already and therefore be caught by catch(Exception ){ … }.
One more thing to note: If you wish your code to behave as it did with C# 1.0 in this area,
you can add the RuntimeCompatibility assembly attribute. Here is the way it should
look, though the code shown here usually appears all on one line:
[assembly:System.Runtime.Compiler
Services.RuntimeCompatibility
(WrapNonExcept ionTh rows =false)]
This will no longer produce the warning since it will also turn off the new CLR 2.0
behavior in which non-System.Exception-derived exceptions are wrapped with
RuntimeWrappedException.

You might also like