2015-05-07 10 views
8

Il CLS è più restrittivo del CLR, che consente di lanciare e catturare qualsiasi tipo di oggetto (anche i tipi di valore). Perché?Perché il CLS richiede il lancio/cattura di oggetti derivati ​​da Eccezione?

Inoltre, cosa succederebbe se un codice non conforme a CLS lanci un oggetto derivato non di eccezione mentre viene chiamato da un codice compatibile con CLS?

UPDATE Seconda domanda risposta da @Marton. Mi chiedo ancora perché.

+0

down-voting dovrebbe essere vietato – MatteoSp

+4

La regola CLS esiste in modo che le eccezioni generate dal codice scritto in una lingua possano essere ragionevolmente catturate dal codice scritto in un altro. Le specifiche CLI non escludono la possibilità che * possa * essere utile in qualche tipo di linguaggio oscuro per lanciare qualcos'altro. Sicuramente avrai difficoltà a trovare un esempio di tale lingua. Quello che succede è in qualche modo ovvio, il programma si blocca senza alcun modo di rilevare o diagnosticare l'eccezione. –

+0

Quindi non è così ovvio, giusto? – MatteoSp

risposta

5

CLS specifica un insieme minimo di caratteristiche linguistiche necessarie da molte applicazioni in modo tale che se un API utilizza solo quelle caratteristiche, può essere consumato da qualsiasi linguaggio conforme a CLS. Quindi, naturalmente, è più restrittivo del CLR. D'altra parte, CLR è progettato per gestire il codice manged da qualsiasi linguaggio conforme alla CLI.

Un esempio di linguaggio che consente di lanciare eccezioni non conformi a CLS (quelle non derivate da System.Exception) è C++/CLI. Questo linguaggio è stato progettato per essere un superset di semplice C++ che include la possibilità di generare eccezioni di qualsiasi tipo. Questa potrebbe essere l'unica buona ragione per generare eccezioni non CLS.

Riguardo alla seconda domanda. Un'eccezione non CLS, quando generata, diverse cose accadono in diversi casi:

  • Se CLR 1.X sta gestendo l'esecuzione del codice, l'eccezione si propaga così com'è. Nelle lingue che supportano solo eccezioni CLS (C#), l'eccezione può essere rilevata solo da un blocco catch senza parametri. Non esiste un modo semplice per accedere all'eccezione e una traccia dello stack non verrà registrata.
  • Su CLR 2.0 e versioni successive, il CLR internamente avvolge sempre l'eccezione in un System.Runtime.CompilerServices.RuntimeWrappedException che mantiene un campo di tipo oggetto che fa riferimento l'eccezione originale. Ciò consente di registrare una traccia stack. Quando si propaga nello stack:

    1. Se l'attributo System.Runtime.CompilerServices.RuntimeCompatibilityAttribute stato applicato sul complesso della funzione in cui il CLR è alla ricerca di un blocco corrispondente cattura e WrapNonExceptionThrows set true (applicato automaticamente dai compilatori Visual C# e Basic), quindi l'eccezione continua a essere completata.

    2. Altrimenti, se l'attributo non sia applicata o se WrapNonExceptionThrows è stato impostato su falso, l'eccezione viene scartato ogni volta un blocco catch viene esaminato per la corrispondenza.

Modifica

In C#, nel primo proiettile sopra e il secondo caso del secondo proiettile, l'unico modo per catturare un'eccezione non-CLS è quello di utilizzare un fermo senza parametri bloccare.

2

Il perché parte non posso rispondere, ma la seconda parte che posso:

cosa accadrebbe se un certo codice non compatibile con CLS ha gettato un Exception oggetto non derivato mentre chiamato da un codice compatibile con CLS?

Se si lancia un oggetto non Exception-derivato, sarà ancora essere catturati dal codice CLS-compliant, dal momento che sarà avvolto in una RuntimeWrappedException.

(Il source article è la pena di leggere per maggiori dettagli.)