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 dalle CLS costituiscono un sottoinsieme del Common Type System. Pertanto, tutte le regole che valgono per il sistema di tipi comuni vengono applicate anche 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 conformi a CLS.

La maggior parte dei membri definiti dai tipi nella libreria di classi .NET Framework sono conformi a CLS. Alcuni tipi della libreria di classi hanno tuttavia uno o più membri non conformi a CLS. Tali membri consentono il supporto di funzionalità di linguaggio non comprese in CLS. I tipi e i membri non conformi sono identificati come tali nella documentazione di riferimento e, in ogni caso, è disponibile un'alternativa conforme a CLS. Per ulteriori informazioni sui tipi inclusi nella libreria di classi .NET Framework, vedere Riferimento a .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 conformi a CLS possano produrre, quando richiesto, codice verificabile. Per ulteriori informazioni sulla verifica dell'indipendenza dai tipi, vedere Processo di esecuzione gestita.

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, vedere la specifica per Common Language Infrastructure, Partition I, disponibile nel sito Web Microsoft Developer Network (MSDN) (informazioni in lingua inglese).

Funzionalità

Si applica a

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 conformi a CLS.

Denominazione

   

   

Caratteri e gestione di maiuscole e minuscole

Tutti

I compilatori di linguaggi conformi a 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. Questo standard è disponibile nel sito Web del Consorzio Unicode (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 conformi a CLS forniscono un meccanismo che permette di fare riferimento a identificatori che coincidono con parole chiave. I compilatori di linguaggi conformi a 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 conforme a 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 conformi a CLS.

Tipi

   

   

Tipi primitivi

Tutti

La libreria di classi .NET Framework include tipi che corrispondono a tipi di dati primitivi utilizzati dai compilatori. Di seguito sono riportati i tipi compatibili con le specifiche CLS: Byte, Int16, Int32, Int64, Single, Double, Boolean, Char, Decimal, IntPtr e String. Per ulteriori informazioni sui tipi, vedere la tabella dei tipi in Riferimento a .NET Framework.

Tipi boxed

Tutti

I tipi valore boxed (tipi valore che sono stati convertiti in oggetti) non fanno parte delle CLS. Utilizzare, invece, System.Object, System.ValueType oppure System.Enum, nel modo appropriato.

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 conformi a 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 conformi a CLS devono essere definiti come conformi a 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 conformi a 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 e, nel caso di metodi generici, al numero dei rispettivi parametri generici.

L'overload dell'operatore 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 dell'operatore sono invitati (ma non vincolati) a seguire tali indicazioni.

Univocità dei membri sottoposti a overload

Tutti

I campi e i tipi annidati 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.

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 conformi a 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 conformi a CLS.

Interfacce

   

   

Firme di membri

Tutti

L'implementazione delle interfacce conformi a CLS non deve richiedere la definizione di metodi non conformi a CLS.

Modificatori di membri

Tutti

Le interfacce conformi a CLS non possono definire metodi static, né possono definire campi. Possono invece definire proprietà, eventi e metodi virtual.

Tipi di 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 conforme alle specifiche CLS deve ereditare da una classe conforme a tali specifiche (System.Object è compatibile con CLS).

Matrici1

   

   

Tipi degli elementi

Tutti

Gli elementi delle matrici devono essere di tipi conformi a CLS.

Dimensioni

Tutti

Le matrici devono avere un numero di dimensioni fisso 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 specifiche 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 insieme 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

I valori letterali 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 conformi a CLS devono operare solo con un sottoinsieme delle codifiche di attributi personalizzati (la rappresentazione degli attributi personalizzati nei metadati). Gli unici 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 le specifiche CLS.

Metadati

   

   

Compatibilità con CLS

Tutti

I tipi la cui compatibilità con le specifiche 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 conforme, occorrerà fornirne un'alternativa conforme a CLS.

Generics

Nomi dei tipi

Compilatori

Il nome di un tipo generico deve codificare il numero dei parametri di tipo dichiarati nel tipo. Il nome di un tipo generico annidato deve codificare il numero dei parametri di tipo appena introdotti nel tipo.

Tipi annidati

Compilatori

I tipi annidati devono avere un numero di parametri generici almeno pari a quelli del tipo di inclusione. I parametri generici di un tipo annidato corrispondono per posizione ai parametri generici del rispettivo tipo di inclusione.

Vincoli

Tutti

Un tipo generico deve dichiarare un numero di vincoli sufficiente a garantire che qualsiasi vincolo delle interfacce o del tipo base venga soddisfatto dai vincoli del tipo generico.

Tipi di vincolo

Tutti

I tipi utilizzati come vincoli sui parametri generici devono essere essi stessi compatibili con le specifiche CLS.

Firme di membri

Tutti

La visibilità e l'accessibilità dei membri (compresi i tipi annidati) in un tipo generico istanziato viene considerata come limitata all'ambito della creazione di istanza specifica, non come dichiarazione del tipo generico nel suo complesso.

Metodi generici

Tutti

Per ogni metodo generico astratto o virtuale è necessaria un'implementazione concreta (non astratta) predefinita

1. Le matrici di matrici sono conformi a CLS. In .NET Framework versione 1.0 il compilatore C# segnala per errore che non sono compatibili.

Vedere anche

Concetti

Interoperabilità tra linguaggi diversi