CLS は CLR よりも制限が厳しく、任意の型のオブジェクト (値型も含む) をスローおよびキャッチできます。なんで?
また、CLS 準拠のコードによって呼び出されたときに、CLS に準拠していないコードが非 Exception 派生オブジェクトをスローした場合はどうなるでしょうか?
UPDATE @Martonが回答した2番目の質問。なぜだろう。
CLS は、API がそれらの機能のみを使用する場合、CLS 準拠の任意の言語で使用できるように、多くのアプリケーションで必要とされる言語機能の最小セットを指定します。したがって、当然、CLR よりも制限が厳しくなります。一方、CLR は、任意の CLI 準拠言語のマネージド コードを処理するように設計されています。
非 CLS 準拠の例外 ( System.Exceptionから派生していないもの) をスローできる言語の例は、C++/CLI です。この言語は、あらゆるタイプの例外をスローする機能を含むプレーン C++ のスーパーセットとして設計されました。これは、CLS 以外の例外をスローする唯一の正当な理由である可能性があります。
2番目の質問について。非 CLS 例外がスローされると、さまざまなケースでさまざまなことが起こります。
CLR 2.0 以降では、CLR は常に内部的に例外をSystem.Runtime.CompilerServices.RuntimeWrappedExceptionにラップします。この例外は、元の例外を参照するObject型のフィールドを維持します。これにより、スタック トレースを記録できます。スタックを伝播するとき:
System.Runtime.CompilerServices.RuntimeCompatibilityAttribute属性が、CLR が一致する catch ブロックを探している関数のアセンブリに適用され、WrapNonExceptionThrowsが true に設定されている場合 (Visual C# および Basic コンパイラによって自動的に適用されます)、例外が続行されます。包む。
それ以外の場合、属性が適用されていない場合、またはWrapNonExceptionThrowsが false に設定されている場合は、catch ブロックが一致するかどうかが検査されるたびに例外がラップ解除されます。
編集
C# では、上記の最初の箇条書きと 2 番目の箇条書きの 2 番目のケースで、CLS 以外の例外をキャッチする唯一の方法は、パラメーターなしの catch ブロックを使用することです。