People who are used to C # and VB. NET may be used to capture all exceptions in the following format:
Try {
// Some code
}
Catch (System. Exception ex ){
System. Console. Write ( " Error! " );
}
Can this statement capture all types of exceptions? Obviously, this statement captures system. Exception and all classes inherited from it.
That is to say, if you throw an object that is not inherited from system. exception, this statement cannot be captured.
Throw an exception that is not an exception ...... Is it possible that this issue is not compatible with CLS?
The answer is: it is possible in 1.x.
In C ++, we can use Throw"Error! "Such a statement throws a string;
In Il, we can use the following method to throw any exceptions:. Assembly throwerlib {}
. Class Public Thrower {
.Method Static Public Void Start (){
Ldstr " Oops "
Throw
RET
}
}
Therefore, in. Net 1.x, the following method is often used: Try
{
// Some code
}
Catch (System. Exception ex)
{
System. Console. writeline ( " System. Exception error: " + Ex. Message );
}
Catch
{
System. Console. writeline ( " Non system. exception based error. );
}
However. in net2.0, to ensure cross-language compatibility, CLR automatically does not inherit from system. exception is wrapped in the runtimewrappedexception object. The result is:CodeAll types of exceptions can be captured.
To ensure compatibility with 1.x,. NET 2.0 provides the runtimecompatibilityattribute class, specifying that CLR does not encapsulate exceptions:
[Assembly: system. runtime. compilerservices. runtimecompatibility (wrapnonexceptionthrows = False )]
Appendix: code for testing (run on. NET 2.0)
1. The IL code that throws a string exception is compiled using ilasm/DLL.//Throwerlib. Il
. Assembly throwerlib {}
. Class Public Thrower {
. Method Static Public Void Throwexception (){
Ldstr " Throwexception exception from the Il world! "
Newobj instance Void [Mscorlib] system. Exception:. ctor ( String )
Throw
RET
}
. method static Public void throwstring () {
ldstr " weird exception! "
throw
RET
}< BR >}
2. Use the C # code for testing. Add a reference to the above DLL.[Assembly: system. runtime. compilerservices. runtimecompatibility (wrapnonexceptionthrows= False)]
Namespace Throwerexample
{
Class Throwerharness
{
Static Void Main ( String [] ARGs)
{
Try
{
Thrower. throwexception ();
}
Catch (System. Exception ex)
{
System. Console. writeline ( " System. Exception error: " + Ex. Message );
}
Catch
{
System. Console. writeline ( " Non system. exception based error. " );
}
Try
{
Thrower. throwstring ();
}
Catch (System. Exception ex)
{
System. Console. writeline ( " System. Exception error: " + Ex. Message );
}
Catch
{
System. Console. writeline ( " Non system. exception based error. " );
}
}
}
}
The execution result is that the first exception will be caught (system. exception ex) {} capture; the second exception is caused by catch (system. exception ex) {} cannot be captured and will be caught.
If the attribute of the first line is removed, the following warning will appear during compilation:
Warning cs1058: a previous catch clause already catches all exceptions. All non-exceptions thrown will be wrapped in a system. runtime. compilerservices. runtimewrappedexception
If the execution continues, both exceptions will be caught by catch (system. Exception ex) {}, and no exceptions will be caught by catch {}.