The CLS is more restrictive than the CLR, which would allow you to throw and catch any type of objects (even value types). Why?
Also what would happen if some non CLS-compliant code threw a non Exception derived object while called by a CLS compliant code?
UPDATE Second question answered by @Marton. Still wonder why.
CLS specifies a minimum set of language features needed by many applications in such a way that if an API uses only those features, it can be consumed by any CLS-compliant language. So naturally it is more restrictive than the CLR. On the other hand, the CLR is deigned to handle manged code from any CLI-compliant language.
An example of a language that allows throwing non-CLS-compliant exceptions (those not derived from System.Exception) is C++/CLI. This language was designed to be a superset of plain C++ which includes the ability to throw exceptions of any type. This could be the only good reason to throw non-CLS exceptions.
Regarding the second question. A non-CLS exception, when thrown, different things happen in different cases:
On CLR 2.0 and later, the CLR internally always wraps the exception into a System.Runtime.CompilerServices.RuntimeWrappedException which maintains a field of type Object that references the original exception. This allows a stack trace to be recorded. When it propagates up the stack:
If the System.Runtime.CompilerServices.RuntimeCompatibilityAttribute attribute was applied on the assembly of the function in which the CLR is looking for a matching catch block and WrapNonExceptionThrows set to true (automatically applied by the Visual C# and Basic compilers), then the exception continues to be wrapped.
Otherwise, if the attribute was not applied or if WrapNonExceptionThrows was set to false, the exception is unwrapped every time a catch block is examined for matching.
Edit
In C#, in the first bullet above and the second case of the second bullet, the only way to catch a non-CLS exception is by using a parameterless catch block.
The why part I cannot answer, but the second part I can:
what would happen if some non CLS-compliant code threw a non Exception derived object while called by a CLS compliant code?
If you throw a non-Exception-derived object, it will still be caught by CLS-compliant code, since it will be wrapped into a RuntimeWrappedException
.
(The source article is worth a read for more details.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With