Descrizione di Common Language Specification
Ai fini dell'interazione con altri oggetti indipendentemente dal linguaggio in cui questi sono stati implementati, occorre che gli oggetti espongano ai chiamanti solo le funzionalità che sono comuni a tutti i linguaggi con cui si desidera che interagiscano. Per questa ragione, è stato definito un set di funzionalità dei linguaggi, denominato Common Language Specification (CLS), che include le funzionalità di base dei linguaggi richieste da numerose applicazioni. Le regole definite da CLS costituiscono un sottoinsieme del sistema di tipi comune. Pertanto, tutte le regole che valgono per il sistema di tipi comune vengono anche applicate per le specifiche CLS, fatta eccezione per i casi in cui queste ultime definiscono regole più rigide. Le specifiche CLS contribuiscono a migliorare e assicurare l'interoperabilità dei linguaggi tramite la definizione di un set di funzionalità che vengono rese disponibili agli sviluppatori di un gran numero di linguaggi. Le specifiche CLS stabiliscono anche i requisiti di compatibilità con le specifiche CLS stesse. In questo modo è possibile determinare se il proprio codice gestito è conforme con CLS ed è possibile sapere in che termini un determinato strumento supporta lo sviluppo di codice gestito che si avvale delle funzionalità di CLS.
Se il proprio componente utilizza solo funzionalità CLS nelle API che espone ad altro codice (comprese le classi derivate), l'accesso al componente è garantito da tutti i linguaggi di programmazione che supportano le specifiche CLS. I componenti che aderiscono alle regole CLS e utilizzano solo le funzionalità incluse in CLS si definiscono componenti compatibili con CLS.
La maggior parte dei membri definiti dai tipi inclusi nella libreria di classi .NET Framework sono compatibili con CLS. Alcuni tipi della libreria di classi hanno tuttavia uno o più membri non compatibili con CLS. Tali membri consentono il supporto di funzionalità di linguaggio non comprese in CLS. I tipi e i membri non compatibili sono identificati come tali nella documentazione di riferimento e, in ogni caso, è disponibile un'alternativa compatibile con CLS. Per informazioni sui tipi inclusi nella libreria di classi .NET Framework, vedere Riferimenti su .NET Framework.
Le specifiche CLS sono state progettate in modo da essere grandi abbastanza da contenere i costrutti di linguaggio comunemente richiesti dagli sviluppatori, ma sufficientemente piccole da poter essere supportate dalla maggior parte dei linguaggi. Ogni costrutto di linguaggio che non consente di verificare rapidamente l'indipendenza del codice dai tipi, è stato inoltre escluso da CLS in modo che tutti i linguaggi compatibili con CLS possano produrre, quando richiesto, codice verificabile. Per ulteriori informazioni sulla verifica dell'indipendenza dai tipi, vedere Compilazione JIT.
La tabella che segue riepiloga le funzionalità di CLS e indica se queste riguardano sia gli sviluppatori che i compilatori (Tutti) o solo i compilatori. Le informazioni riportate non sono da considerarsi esaustive. Per informazioni dettagliate, consultare le specifiche di Common Language Infrastructure, Parte I, riportate nella directory della Guida per gli sviluppatori di strumenti installata con Microsoft .NET Framework SDK.
Funzionalità | Riguarda | Descrizione |
---|---|---|
Generale | ||
Visibilità |
Tutti | Le regole CLS valgono solo per quelle parti dei tipi che sono esposte all'esterno dell'assembly che li definisce. |
Membri globali |
Tutti | I metodi e i campi static globali non sono compatibili con CLS. |
Denominazione | ||
Caratteri e gestione di maiuscole e minuscole |
Tutti | I compilatori di linguaggi compatibili con CLS devono osservare le regole dell'allegato 7 del Technical Report 15 di Unicode Standard 3.0, che definisce gli insiemi di caratteri che possono essere utilizzati all'inizio e all'interno degli identificatori. Tale standard è disponibile all'indirizzo www.unicode.org/unicode/reports/tr15/tr15-18.html (informazioni in lingua inglese).
Perché due identificatori vengano considerati distinti, occorre che non differiscano solo per la combinazione di caratteri maiuscoli o minuscoli. |
Parole chiave |
Compilatori | I compilatori di linguaggi compatibili con CLS forniscono un meccanismo che permette di fare riferimento a identificatori che coincidono con parole chiave. I compilatori di linguaggi compatibili con CLS forniscono un meccanismo per la definizione e l'override di metodi virtuali aventi nomi che corrispondono a parole chiave del linguaggio. |
Univocità |
Tutti | Tutti i nomi appartenenti a un ambito compatibile con CLS devono essere univoci, anche se individuano due diversi tipi di membri, fatta eccezione per il caso di nomi identici risolti tramite overload. Le specifiche CLS, ad esempio, non consentono a un unico tipo di utilizzare lo stesso nome per un metodo e per un campo. |
Firme |
Tutti | Tutti i tipi restituiti e i tipi di parametri che appaiono in una firma di membro o di tipo devono essere compatibili con CLS. |
Tipi | ||
Tipi primitivi |
Tutti | La libreria di classi .NET Framework include tipi che corrispondono a tipi di dati primitivi utilizzati dai compilatori. Di tali tipi, quelli indicati di seguito sono compatibili con CLS: Byte, Int16, Int32, Int64, Single, Double, Boolean, Char, Decimal, IntPtr, and String. Per ulteriori informazioni su questi tipi, vedere la tabella dei tipi in Libreria di classi .NET Framework. |
Tipi boxed |
Tutti | I tipi valore boxed (tipi valore che sono stati convertiti in oggetti) non fanno parte delle CLS. Utilizzare invece il più appropriato tra System.Object, System.ValueType o System.Enum. |
Visibilità |
Tutti | Le dichiarazioni di tipi e membri non devono contenere tipi meno visibili o accessibili dei tipi o dei membri che si sta dichiarando. |
Metodi di interfaccia |
Compilatori | I compilatori di linguaggi compatibili con CLS devono prevedere una sintassi per la circostanza in cui un singolo tipo implementa due interfacce e ciascuna di tali interfacce richiede la definizione di un metodo con lo stesso nome e la stessa firma. Tali metodi devono essere considerati distinti e avere implementazioni diverse. |
Vicinanza |
Tutti | I singoli membri di classi astratte e interfacce compatibili con CLS devono essere definiti come compatibili con CLS. |
Chiamata di un costruttore |
Tutti | Prima di accedere ai dati di istanza ereditati, un costruttore deve chiamare il costruttore della classe base. |
Riferimenti tipizzati |
Tutti | I riferimenti tipizzati non sono compatibili con CLS. Un riferimento tipizzato è uno speciale costrutto che contiene un riferimento a un oggetto e un riferimento a un tipo. I riferimenti tipizzati consentono a Common Language Runtime di fornire il supporto in stile C++ per i metodi che hanno un numero variabile di argomenti. |
Membri dei tipi | ||
Overload |
Tutti | Le proprietà indicizzate, i metodi e i costruttori possono essere sottoposti a overload. I campi e gli eventi non devono essere sottoposti a overload.
Le proprietà non devono essere sottoposte a overload del tipo (cioè del tipo restituito dal relativo metodo di richiamo), ma possono essere sottoposte a overload che ne alterino il numero o il tipo di indici. L'overload dei metodi può essere effettuato solo in base al numero e ai tipi dei relativi parametri. L'overload degli operatori non è contemplato da CLS. Le specifiche CLS includono comunque indicazioni su come fornire nomi utili (quali Add()) e su come impostare un bit nei metadati. I compilatori che scelgono di supportare l'overload degli operatori sono invitati (ma non vincolati) a seguire tali indicazioni. |
Univocità dei membri sottoposti a overload |
Tutti | I campi e i tipi nidificati devono risultare distinti al confronto degli identificatori. I metodi, le proprietà e gli eventi che hanno lo stesso nome (in base al confronto degli identificatori) devono presentare differenze che vanno oltre il tipo restituito. |
Operatori di conversione |
Tutti | Se op_Implicit o op_Explicit viene sottoposto a overload del tipo restituito, occorre fornire un metodo alternativo di conversione. |
Metodi | ||
Accessibilità dei metodi sottoposti a override |
Tutti | L'accessibilità non deve essere modificata quando si esegue l'override di metodi ereditati, tranne nel caso in cui si esegua l'override di un metodo ereditato da un assembly diverso con accessibilità FamilyOrAssembly. In questo caso, l'override deve avere accessibilità Family. |
Elenco di argomenti |
Tutti | L'unica convenzione di chiamata supportata da CLS è la convenzione di chiamata gestita standard. L'utilizzo di elenchi di argomenti di lunghezza variabile non è consentito. Per il supporto di un numero di argomenti di lunghezza variabile, utilizzare la parola chiave ParamArray in Microsoft Visual Basic e la parola chiave params in C#. |
Proprietà | ||
Metadati delle funzioni di accesso |
Compilatori | I metodi di richiamo e di impostazione che implementano i metodi di una proprietà sono contrassegnati con l'identificatore mdSpecialName nei metadati. |
Accessibilità delle funzioni di accesso |
Tutti | L'accessibilità della proprietà e delle relative funzioni di accesso devono essere identiche. |
Modificatori |
Tutti | La proprietà e le relative funzioni di accesso devono essere tutte static, tutte virtual o tutte instance. |
Nomi delle funzioni di accesso |
Tutti | La denominazione delle proprietà deve osservare criteri specifici. Per una proprietà denominata Name, il metodo di richiamo, se definito, dovrà essere denominato get_Name e il metodo di impostazione, se definito, dovrà essere denominato set_Name. |
Tipi restituiti e argomenti |
Tutti | Il tipo della proprietà è il tipo restituito del relativo metodo di richiamo e il tipo dell'ultimo argomento del metodo di impostazione. I tipi dei parametri della proprietà sono i tipi dei parametri del metodo di richiamo e i tipi di tutti i parametri del metodo di impostazione tranne l'ultimo. È necessario che tutti i tipi sopra citati siano compatibili con CLS e che non siano puntatori gestiti. Non è possibile passarli per riferimento. |
Eventi | ||
Metodi di evento |
Tutti | È necessario che i metodi per l'aggiunta e la rimozione di un evento siano entrambi presenti o assenti. |
Metadati dei metodi di evento |
Compilatori | È necessario che i metodi che implementano un evento siano contrassegnati con l'identificatore mdSpecialName nei metadati. |
Accessibilità delle funzioni di accesso |
Tutti | È necessario che le accessibilità dei metodi per l'aggiunta, la rimozione e la generazione di un evento siano identiche. |
Modificatori |
Tutti | È necessario che i metodi per l'aggiunta, la rimozione e la generazione di un evento siano tutti static, tutti virtual o tutti instance. |
Nomi dei metodi di evento |
Tutti | La denominazione degli eventi deve osservare criteri specifici. Per un evento denominato MyEvent, il metodo di aggiunta, se definito, dovrà essere denominato add_MyEvent, il metodo di rimozione, se definito, dovrà essere denominato remove_MyEvent e il metodo di generazione dovrà essere denominato raise_MyEvent. |
Argomenti |
Tutti | I metodi per l'aggiunta e la rimozione di un evento devono entrambi accettare un parametro il cui tipo definisce il tipo dell'evento e tale tipo deve essere derivato da System.Delegate. |
Tipi puntatore | ||
Puntatori |
Tutti | I tipi puntatore e i tipi puntatore a funzione non sono compatibili con CLS. |
Interfacce | ||
Firme di membri |
Tutti | L'implementazione delle interfacce compatibili con CLS non deve richiedere la definizione di metodi non compatibili con CLS. |
Modificatori di membri |
Tutti | Le interfacce compatibili con CLS non possono definire metodi static, né possono definire campi. Possono invece definire proprietà, eventi e metodi virtual. |
Tipi riferimento | ||
Chiamata di un costruttore |
Tutti | Per i tipi riferimento, i costruttori degli oggetti vengono chiamati solo nell'ambito della creazione di un oggetto e gli oggetti vengono inizializzati una sola volta. |
Tipi classe | ||
Ereditarietà |
Tutti | Una classe compatibile con CLS deve ereditare da una classe compatibile con CLS (System.Object è compatibile con CLS). |
Matrici | ||
Tipi degli elementi |
Tutti | Gli elementi delle matrici devono essere di tipi compatibili con CLS. |
Dimensioni |
Tutti | Le matrici devono avere un numero di dimensioni fisso e maggiore di zero. |
Limiti |
Tutti | Il limite inferiore di tutte le dimensioni di una matrice deve essere uguale a zero. |
Enumerazioni | ||
Tipo sottostante |
Tutti | Il tipo sottostante di un'enumerazione deve essere un tipo integer incorporato nelle CLS (Byte, Int16, Int32 o Int64). |
FlagsAttribute |
Compilatori | La presenza dell'attributo personalizzato System.FlagsAttribute nella definizione di un enumerazione indica che l'enumerazione deve essere trattata come set di campi di bit (flag), mentre l'assenza di tale attributo indica che il tipo deve essere visto come un gruppo di costanti enumerate. È importante che i linguaggi utilizzino FlagsAttribute o una sintassi specifica del linguaggio per distinguere tra questi due tipi di enumerazioni. |
Membri campo |
Tutti | Le rappresentazioni formali dei campi static di un'enumerazione devono essere dello stesso tipo dell'enumerazione stessa. |
Eccezioni | ||
Ereditarietà |
Tutti | Gli oggetti che vengono generati devono essere di tipo System.Exception o ereditare da System.Exception. |
Attributi personalizzati | ||
Codifiche di valori |
Compilatori | I compilatori compatibili con CLS devono operare solo con un sottoinsieme delle codifiche di attributi personalizzati (la rappresentazione degli attributi personalizzati nei metadati). I soli tipi che possono apparire in tali codifiche sono: System.Type, System.String, System.Char, System.Boolean, System.Byte, System.Int16, System.Int32, System.Int64, System.Single, System.Double e qualsiasi tipo di enumerazione basato su un tipo base integer compatibile con CLS. |
Metadati | ||
Compatibilità con CLS |
Tutti | I tipi la cui compatibilità con CLS differisce da quella dell'assembly in cui sono definiti devono essere contrassegnati come tali con l'attributo System.CLSCompliantAttribute. Analogamente, devono essere contrassegnati anche i membri la cui compatibilità con CLS differisce da quella del relativo tipo. Se un membro o un tipo è contrassegnato come non compatibile, occorrerà fornirne un'alternativa compatibile con CLS. |
Vedere anche
Interoperabilità tra linguaggi diversi | Cenni preliminari sull'interoperabilità dei linguaggi