2015-05-07 8 views
8

Die CLS ist restriktiver als die CLR, mit der Sie beliebige Arten von Objekten (sogar Wertetypen) werfen und abfangen können. Warum?Warum erfordert das CLS das Werfen/Fangen von Ausnahme-abgeleiteten Objekten?

Auch was passiert, wenn ein nicht CLS-konformer Code ein nicht von Exception abgeleitetes Objekt auslöst, während es von einem CLS-konformen Code aufgerufen wird?

UPDATE Zweite Frage von @Marton beantwortet. Ich frage mich immer noch warum.

+0

Down-Voting ohne zu erklären, sollte verboten werden – MatteoSp

+4

Die CLS-Regel existieren so Ausnahmen, die durch Code in einer Sprache geschrieben werden, können vernünftigerweise durch Code in einem anderen Code gefangen werden. Die CLI-Spezifikation schließt die Möglichkeit nicht aus, dass es * in irgendeiner Art von obskurer Sprache nützlich sein könnte, etwas anderes zu werfen. Sicherlich fällt es Ihnen schwer, ein Beispiel für eine solche Sprache zu finden. Was passiert, ist etwas offensichtlich, das Programm stürzt ab und es gibt keine Möglichkeit, die Ausnahme zu erfassen oder zu diagnostizieren. –

+0

So stellt sich heraus, ist nicht so offensichtlich, oder? – MatteoSp

Antwort

5

CLS einen Mindestsatz von Sprachfunktionen gibt viele Anwendungen in einer solchen Art und Weise erforderlich, dass, wenn eine API nur die Funktionen verwendet, kann sie durch verbraucht werden jede CLS-konforme Sprache. 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 verarbeitet.

Ein Beispiel für eine Sprache, die das Werfen von Nicht-CLS-konformen Ausnahmen (die nicht von System.Exception abgeleitet sind) erlaubt, 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.

In Bezug auf die zweite Frage. Wenn eine CLS-Ausnahme ausgelöst wird, treten in verschiedenen Fällen unterschiedliche Ursachen auf:

  • Wenn CLR 1.X die Ausführung des Codes verwaltet, wird die Ausnahme unverändert weitergegeben. In Sprachen, die nur CLS-Ausnahmen (C#) unterstützen, kann die Ausnahme nur von einem parameterlosen catch-Block abgefangen werden. Es gibt keine einfache Möglichkeit, auf die Ausnahme zuzugreifen, und ein Stack-Trace wird nicht aufgezeichnet.
  • Auf CLR 2.0 und höher, wickelt sich die CLR intern immer die Ausnahme in einem System.Runtime.CompilerServices.RuntimeWrappedException die ein Feld vom Typ Objekt verwaltet, der die ursprüngliche Ausnahme verweist. Dies ermöglicht das Aufzeichnen einer Stapelspur. Wenn es um den Stapel ausbreitet up:

    1. Wenn das System.Runtime.CompilerServices.RuntimeCompatibilityAttribute Attribut für die Montage der Funktion, in der Anwendung wurde die CLR sucht nach einer passenden Sperranschlag und WrapNonExceptionThrows set true (wird automatisch von den Visual C# - und Basic-Compilern angewendet), dann wird die Exception weiterhin umbrochen.

    2. Andernfalls, wenn das Attribut nicht angewendet wurde, oder wenn WrapNonExceptionThrows auf false gesetzt wurde, wird die Ausnahme jedes Mal, wenn ein Fangblock ist für den Abgleich untersucht ausgepackt.

bearbeiten

In C# in der ersten Kugel oben und den zweiten Fall der zweiten Kugel, die einzige Möglichkeit, eine nicht-CLS Ausnahme durch die Verwendung eines parameter Haken ist, zu fangen Block.

2

Der warum Teil kann ich nicht beantworten, aber der zweite Teil kann ich:

, was passieren würde, wenn einige nicht CLS-konformen Code ein nicht Exception abgeleitete Objekt geworfen, während sie von einem CLS-konformen Code aufgerufen?

Wenn Sie eine nicht-Exception abgeleitete Objekt werfen, wird es noch von CLS-konformen Code abgefangen werden, werden, da sie in eine RuntimeWrappedException gewickelt werden.

(Die source article ist lesenswert für weitere Details.)