Der CLS ist restriktiver als der CLR, mit dem Sie beliebige Arten von Objekten (sogar Wertetypen) werfen und abfangen können. Warum?
Was würde auch passieren, wenn ein nicht CLS-konformer Code ein nicht von Exception abgeleitetes Objekt auslöst, während er von einem CLS-konformen Code aufgerufen wird?
UPDATE Zweite Frage von @Marton beantwortet. Ich frage mich immer noch warum.
CLS gibt einen Mindestsatz von Sprachfeatures an, die von vielen Anwendungen auf eine Weise benötigt werden, dass, wenn eine API nur diese Features verwendet, diese von jeder CLS-kompatiblen Sprache verwendet werden kann. Es ist also natürlich restriktiver als die CLR. Auf der anderen Seite ist die CLR so ausgelegt, dass sie verwalteten Code von jeder CLI-konformen Sprache aus behandelt.
Ein Beispiel für eine Sprache, die es ermöglicht, Nicht-CLS-konforme Ausnahmen (die nicht von System.Exception abgeleitet sind) zu werfen, ist C ++ / CLI. Diese Sprache wurde entworfen, um eine Obermenge von reinem C ++ zu sein, die die Fähigkeit enthält, Ausnahmen jeglicher Art zu werfen. Dies könnte der einzige gute Grund sein, Nicht-CLS-Ausnahmen auszulösen.
Zur zweiten Frage. Eine Nicht-CLS-Ausnahme, bei der verschiedene Dinge passieren, geschieht in verschiedenen Fällen:
Bei CLR 2.0 und höher wird die Ausnahme von der CLR intern immer in eine System.Runtime.CompilerServices.RuntimeWrappedException eingeschlossen, die ein Feld vom Typ Objekt verwaltet, das auf das Original verweist Ausnahme. Dies ermöglicht das Aufzeichnen einer Stapelspur. Wenn es sich im Stapel ausbreitet:
Wenn das Attribut System.Runtime.CompilerServices.RuntimeCompatibilityAttribute auf die Assembly der Funktion angewendet wurde, in der die CLR nach einem passenden catch-Block sucht, und WrapNonExceptionThrows auf true setzen (wird automatisch von den Visual C # - und Basic-Compilern angewendet), dann wird die Ausnahme weiterhin umbrochen.
Andernfalls, wenn das Attribut nicht angewendet wurde oder WrapNonExceptionThrows auf "false" gesetzt war, wird die Ausnahme jedes Mal ausgepackt, wenn ein catch-Block auf Übereinstimmung geprüft wird.
Bearbeiten
In C #, in der ersten Kugel oben und im zweiten Fall der zweiten Kugel, ist die einzige Möglichkeit, eine Nicht-CLS-Ausnahme zu fangen, die Verwendung eines parameterlosen Fangblocks.
Der Warum Teil kann ich nicht beantworten, aber der zweite Teil kann ich:
Was passiert, wenn ein nicht CLS-konformer Code eine Ausnahme auslöst? abgeleitetes Objekt, während es von einem CLS-konformen Code aufgerufen wird?
Wenn Sie ein Objekt werfen, das nicht von Exception abgeleitet ist, wird es weiterhin vom CLS-konformen Code abgefangen, da es in ein RuntimeWrappedException
eingebunden wird.
(Der Quellartikel ist für weitere Details eine Lektüre wert.)