Token di metadati
I metadati fanno riferimento a informazioni dichiarative sulle astrazioni, inclusi i tipi in fase di esecuzione (classi, tipi di valore e interfacce), le funzioni globali e le variabili globali. I metadati sono archiviati in tabelle, una per ogni categoria di astrazione con una riga per ogni dichiarazione di un'astrazione. Un token, ovvero un oggetto di tipo mdToken, consente di individuare il record che contiene i metadati per un'astrazione. Il modulo di gestione dei metadati utilizza il token per effettuare l'indicizzazione in una specifica tabella dei metadati in un determinato ambito dei metadati.
Struttura dei token di metadati
Un token di metadati è un valore a 4 byte. Il byte più significativo (MSB, Most Significant Byte) specifica il tipo di token e di conseguenza identifica l'astrazione e la relativa tabella dei metadati associata. Ad esempio, un valore 1 nel byte più significativo indica che il token è un token mdTypeRef che rappresenta un riferimento al tipo e che i metadati sono archiviati nella relativa tabella TypeRef. Un valore 4 corrisponde invece a un token mdFieldDef. L'enumerazione CorTokenType viene utilizzata per specificare i tipi di token.
I tre byte meno significativi, noti come identificatore record (RID, Record Identifier), contengono l'indice della riga della tabella dei metadati a cui fa riferimento il byte più significativo del token. Ad esempio, il token di metadati con valore 0x02000007 fa riferimento alla riga 7 della tabella TypeDef nell'ambito corrente. Analogamente , il token 0x0400001A fa riferimento alla riga 26 (decimale) della tabella FieldDef nell'ambito corrente. Nella riga zero di una tabella dei metadati non sono mai presenti dati, pertanto un token di metadati con RID zero viene indicato come token Null. L'API dei metadati definisce un host di tali token Null, uno per ogni tipo di token, ad esempio mdTypeRefNil, con valore 0x01000000.
Nota |
---|
La precedente descrizione dei RID è a livello concettuale. In realtà, il layout fisico dei metadati è molto più complesso.I token di stringa (mdString), inoltre, sono leggermente diversi, in quanto i 3 byte meno significativi non costituiscono degli identificatori record, bensì un offset dalla posizione iniziale della stringa nel pool di stringhe di metadati. |
Utilizzo dei token di metadati
Ogni metodo DefineXXX dell'API dei metadati restituisce un token che può essere passato a un metodo GetXXX per ottenere gli attributi associati.
I token di metadati sono definiti all'interno di un ambito. Un token di metadati con valore N , ad esempio, identifica completamente, all'interno di un determinato ambito, un record che contiene i dettagli su una definizione di tipo. In un ambito diverso, un token di metadati con lo stesso valore N può invece specificare un record totalmente differente.
Un token di metadati non è un identificatore non modificabile dell'oggetto dei metadati. Quando si uniscono due ambiti, il mapping dei token dell'ambito importato nei token dell'ambito generato viene modificato. Quando un ambito dei metadati viene salvato, le diverse ottimizzazioni del formato possono portare a un nuovo mapping dei token.
Tipi di token
Nella tabella che segue sono riportati i tipi di token di metadati, l'astrazione che ogni tipo di token rappresenta e il nome della tabella dei metadati che contiene i metadati dell'astrazione. Tutti i tipi di token sono variazioni di mdToken, che è il tipo di token di base.
Tipo di token |
Tabella dei metadati |
Astrazione |
---|---|---|
mdModule |
Modulo |
Modulo: unità di compilazione, file eseguibile o altra unità di sviluppo, di distribuzione o di runtime. È possibile (sebbene non necessario) dichiarare gli attributi sul modulo complessivamente, inclusi un nome, un GUID, attributi personalizzati e così via. |
mdModuleRef |
ModuleRef |
Riferimento al modulo: riferimento in fase di compilazione a un modulo, che registra l'origine per le importazioni di tipo e membro. |
mdTypeDef |
Typedef |
Dichiarazione di tipo: dichiarazione di un tipo riferimento in fase di esecuzione (classe o interfaccia) oppure di un tipo valore. |
mdTypeRef |
TypeRef |
Riferimento al tipo: riferimento a un tipo riferimento in fase di esecuzione oppure a un tipo valore. In un certo senso, l'insieme di riferimenti tipo in un modulo è l'insieme delle dipendenze di importazione in fase di compilazione. |
mdMethodDef |
MethodDef |
Definizione di metodo: definizione di un metodo come membro di una classe o di un'interfaccia oppure come metodo globale a livello di modulo. |
mdParamDef |
ParamDef |
Dichiarazione di parametro: definizione di una struttura dati facoltativa in cui sono archiviati metadati aggiuntivi per il parametro. Non è necessario generare una struttura dati per ogni parametro di un metodo. Quando tuttavia vi sono ulteriori metadati da salvare in modo permanente per il parametro, ad esempio le informazioni per il marshalling o il mapping dei tipi, può essere creata una struttura dei dati dei parametri facoltativa. |
mdFieldDef |
FieldDef |
Dichiarazione di campo: dichiarazione di una variabile come membro dati di una classe o di un'interfaccia oppure dichiarazione di una variabile globale a livello di modulo. |
mdProperty |
Property |
Dichiarazione di proprietà: dichiarazione di una proprietà come membro di una classe o di un'interfaccia. |
mdEvent |
Evento |
Dichiarazione di evento: dichiarazione di un determinato denominato come membro di una classe o di un'interfaccia. |
mdMemberRef |
MemberRef |
Riferimento al membro: riferimento a un metodo oppure a un campo. Nei metadati viene generato un riferimento al membro per ogni chiamata a un metodo o per ogni accesso a un campo effettuato da qualsiasi implementazione nel modulo corrente e un token viene salvato in modo permanente nel flusso MSIL (Microsoft Intermediate Language). Non vi è supporto in fase di esecuzione per i riferimenti a proprietà o eventi. |
mdIfaceImpl |
IfaceImpl |
Implementazione dell'interfaccia: implementazione di una classe specifica di un'interfaccia specifica. Questa astrazione dei metadati consente l'archiviazione di informazioni che costituiscono l'intersezione delle informazioni che non sono specifiche né della classe né dell'interfaccia. |
mdMethodImpl |
MethodImpl |
Implementazione del metodo: implementazione di una classe specifica di un metodo ereditato tramite l'ereditarietà dell'interfaccia. Questa astrazione dei metadati consente di salvare in modo permanente le informazioni specifiche dell'implementazione piuttosto che quelle specifiche del contratto. Le informazioni di dichiarazione del metodo non possono essere modificate mediante la classe di implementazione. |
mdCustomAttribute |
CustomAttribute |
Attributo personalizzato: struttura dati arbitraria associata a qualsiasi oggetto di metadati a cui è possibile fare riferimento tramite un token mdToken. L'unica eccezione è rappresentata dal fatto che gli attributi personalizzati non possono avere attributi personalizzati. |
mdPermission |
Autorizzazione |
Set di autorizzazioni: set di autorizzazioni di sicurezza dichiarativa associato ai token mdTypeDef, mdMethodDef e mdAssembly. Per ulteriori informazioni, vedere Aggiunta del supporto della sicurezza dichiarativa. |
mdTypeSpec |
TypeSpec |
Costruttore del tipo: metodo che ottiene un token per un tipo, ad esempio un tipo di valore boxed, che può essere utilizzato come input per qualsiasi istruzione MSIL che accetti un tipo. |
mdSignature |
Signature |
Firma autonoma: firma della variabile locale nel file eseguibile di tipo PE o firma di un metodo passata a un'istruzione MSIL. |
mdString |
String |
Stringa utente: stringa passata a un'istruzione MSIL. |
Nota |
---|
Nell'elenco precedente non sono inclusi due tipi di token distinti, uno per un riferimento al campo e un altro per un riferimento al metodo, come prevedibile.I riferimenti al campo e al metodo condividono la stessa tabella e possono utilizzare come riferimento il tipo di token mdMemberRef. |
Estensibilità e astrazioni
I metadati di runtime sono estendibili, caratteristica importante nei seguenti scenari:
Per rappresentare vincoli o astrazioni di livello superiore definite dalle specifiche CLS (Common Language Specification). CLS è una specifica per le convenzioni a cui i linguaggi e gli strumenti aderiscono in modo uniforme per garantire una migliore integrazione. CLS può vincolare parti del modello del sistema di tipi comuni e può introdurre astrazioni di livello superiore che si sovrappongono a tale sistema. I metadati devono poter acquisire questi tipi di astrazioni della fase di sviluppo utilizzate dagli strumenti, anche se le astrazioni non sono riconosciute o supportate in modo esplicito dal runtime.
Per rappresentare astrazioni specifiche del linguaggio che non fanno parte del sistema di tipi comuni e che non sono astrazioni di CLS. In questo modo, linguaggi quali Visual C non necessitano di file IDL o file di intestazione separati per poter utilizzare tipi, metodi e membri dati esportati dai moduli compilati.
Per codificare i tipi di firma interni ai membri e i modificatori di tipi utilizzati nell'overload specifico del linguaggio.
L'estensibilità dei metadati viene garantita nei seguenti modi:
Ogni oggetto dei metadati può supportare attributi personalizzati e le API dei metadati consentono di dichiarare, enumerare e recuperare tali attributi, i quali possono essere identificati da un riferimento al tipo, ovvero mdTypeDef e mdTypeRef. La struttura dell'attributo personalizzato è autodescrittiva in quanto utilizza membri dati dichiarati sul tipo. La codifica dei valori è visualizzabile tramite qualsiasi strumento, inclusi i servizi di reflection del runtime.
Oltre a estendere il sistema di tipi comuni, è possibile generare modificatori personalizzati in firme dei membri. Il runtime rispetterà questi modificatori per eseguire l'overload e nascondere i metodi, nonché per effettuare l'associazione, ma non applicherà alcuna semantica specifica del linguaggio.