Metadati e componenti auto-descrittiviMetadata and Self-Describing Components

In passato, un componente software (EXE o DLL) scritto in un linguaggio non poteva usare facilmente un componente software scritto in un linguaggio diverso.In the past, a software component (.exe or .dll) that was written in one language could not easily use a software component that was written in another language. Il sistema COM ha costituito un passo in avanti nella soluzione di questo problema.COM provided a step towards solving this problem. Oggi .NET Framework rende l'interazione tra i componenti ancora più semplice consentendo ai compilatori di inserire informazioni dichiarative aggiuntive in tutti i moduli e in tutti gli assembly.The .NET Framework makes component interoperation even easier by allowing compilers to emit additional declarative information into all modules and assemblies. Queste informazioni, note come metadati, semplificano l'interazione tra i componenti.This information, called metadata, helps components to interact seamlessly.

I metadati sono informazioni binarie che descrivono un programma e vengono memorizzate in un file eseguibile portabile (PE, Portable Executable) di Common Language Runtime o in memoria.Metadata is binary information describing your program that is stored either in a common language runtime portable executable (PE) file or in memory. Quando si compila il proprio codice in un file PE, i metadati vengono inseriti in una parte del file e il codice viene convertito in Microsoft Intermediate Language (MSIL) e inserito in un'altra parte del file.When you compile your code into a PE file, metadata is inserted into one portion of the file, and your code is converted to Microsoft intermediate language (MSIL) and inserted into another portion of the file. Ogni tipo e membro definito e a cui si fa riferimento in un modulo o in un assembly è descritto nei metadati.Every type and member that is defined and referenced in a module or assembly is described within metadata. Quando il codice viene eseguito, il runtime carica i metadati in memoria e vi fa riferimento per ottenere informazioni sulle classi usate nel codice, come pure su membri, ereditarietà e così via.When code is executed, the runtime loads metadata into memory and references it to discover information about your code's classes, members, inheritance, and so on.

I metadati consentono di descrivere ciascun tipo e membro definito nel codice in modo indipendente dal linguaggio.Metadata describes every type and member defined in your code in a language-neutral manner. I metadati archiviano le seguenti informazioni:Metadata stores the following information:

  • Descrizione dell'assembly.Description of the assembly.

    • Identità (nome, versione, impostazioni cultura, chiave pubblica).Identity (name, version, culture, public key).

    • Tipi esportati.The types that are exported.

    • Altri assembly da cui questo assembly dipende.Other assemblies that this assembly depends on.

    • Autorizzazioni di sicurezza necessarie per l'esecuzione.Security permissions needed to run.

  • Descrizione di tipi.Description of types.

    • Nome, visibilità, classe base e interfacce implementate.Name, visibility, base class, and interfaces implemented.

    • Membri (metodi, campi, proprietà, eventi e tipi annidati).Members (methods, fields, properties, events, nested types).

  • Attributi.Attributes.

    • Elementi descrittivi aggiuntivi che modificano tipi e membri.Additional descriptive elements that modify types and members.

Vantaggi offerti dai metadatiBenefits of Metadata

I metadati costituiscono la chiave di un modello di programmazione più semplice ed eliminano la necessità di file del linguaggio di definizione dell'interfaccia (IDL, Interface Definition Language), di file di intestazione o di qualsiasi altro metodo esterno di riferimento ai componenti.Metadata is the key to a simpler programming model, and eliminates the need for Interface Definition Language (IDL) files, header files, or any external method of component reference. I metadati consentono ai linguaggi .NET Framework di descrivere se stessi automaticamente e in modo indipendente dal linguaggio, in modo trasparente sia per lo sviluppatore che per l'utente.Metadata enables .NET Framework languages to describe themselves automatically in a language-neutral manner, unseen by both the developer and the user. Le capacità dei metadati possono inoltre essere estese con l'uso degli attributi.Additionally, metadata is extensible through the use of attributes. I metadati offrono i seguenti vantaggi principali:Metadata provides the following major benefits:

  • File autodescrittivi.Self-describing files.

    I moduli e gli assembly di Common Language Runtime sono autodescrittivi.Common language runtime modules and assemblies are self-describing. I metadati di un modulo contengono tutto il necessario per interagire con un altro modulo.A module's metadata contains everything needed to interact with another module. I metadati forniscono automaticamente le funzionalità di IDL in COM, consentendo di utilizzare un solo file sia per la definizione che per l'implementazione.Metadata automatically provides the functionality of IDL in COM, so you can use one file for both definition and implementation. Moduli e assembly di runtime non richiedono la registrazione presso il sistema operativo.Runtime modules and assemblies do not even require registration with the operating system. Pertanto, le descrizioni usate dal runtime rispecchiano sempre il codice effettivamente presente nel file compilato, incrementando così l'affidabilità dell'applicazione.As a result, the descriptions used by the runtime always reflect the actual code in your compiled file, which increases application reliability.

  • Interoperabilità dei linguaggi e progettazione basata su componenti semplificata.Language interoperability and easier component-based design.

    I metadati forniscono tutte le informazioni relative al codice compilato che occorrono per ereditare una classe da un file PE scritto in un linguaggio diverso.Metadata provides all the information required about compiled code for you to inherit a class from a PE file written in a different language. È possibile creare un'istanza di una classe scritta in uno dei linguaggi gestiti (qualsiasi linguaggio che si avvale di Common Language Runtime) senza preoccuparsi del marshalling esplicito e senza utilizzare codice di interoperabilità personalizzato.You can create an instance of any class written in any managed language (any language that targets the common language runtime) without worrying about explicit marshaling or using custom interoperability code.

  • Attributi.Attributes.

    .NET Framework consente di dichiarare tipi specifici di metadati, detti attributi, nel proprio file compilato.The .NET Framework lets you declare specific kinds of metadata, called attributes, in your compiled file. Gli attributi sono disponibili nell'intero contesto di .NET Framework e vengono utilizzati per controllare in maggior dettaglio come si comporta il proprio programma in fase di esecuzione.Attributes can be found throughout the .NET Framework and are used to control in more detail how your program behaves at run time. È inoltre possibile inserire i propri metadati personalizzati nei file di .NET Framework tramite attributi personalizzati definiti dall'utente.Additionally, you can emit your own custom metadata into .NET Framework files through user-defined custom attributes. Per altre informazioni, vedere Attributi.For more information, see Attributes.

I metadati e la struttura dei file PEMetadata and the PE File Structure

I metadati vengono memorizzati in una sezione di un file eseguibile portabile (PE, Portable Executable) .NET Framework, mentre il codice Microsoft Intermediate Language (MSIL) viene memorizzato in una diversa sezione dello stesso file.Metadata is stored in one section of a .NET Framework portable executable (PE) file, while Microsoft intermediate language (MSIL) is stored in another section of the PE file. La parte del file che ospita i metadati contiene una serie di tabelle e di strutture di dati dell'heap.The metadata portion of the file contains a series of table and heap data structures. La parte MSIL contiene codice MSIL e token di metadati che fanno riferimento alla parte del file PE che ospita i metadati.The MSIL portion contains MSIL and metadata tokens that reference the metadata portion of the PE file. I token dei metadati vengono usati, ad esempio, con strumenti come il disassemblatore MSIL (Ildasm.exe), che consente di visualizzare il proprio codice MSIL.You might encounter metadata tokens when you use tools such as the MSIL Disassembler (Ildasm.exe) to view your code's MSIL, for example.

Tabelle e heap dei metadatiMetadata Tables and Heaps

Ogni tabella dei metadati contiene informazioni sugli elementi di un programma.Each metadata table holds information about the elements of your program. Ad esempio, una tabella dei metadati descrive le classi presenti nel codice, un'altra tabella descrive i campi e così via.For example, one metadata table describes the classes in your code, another table describes the fields, and so on. Se il codice contiene dieci classi, la tabella delle classi sarà costituita da dieci righe, una per ogni classe.If you have ten classes in your code, the class table will have tens rows, one for each class. Le tabelle dei metadati fanno riferimento ad altre tabelle e agli heap.Metadata tables reference other tables and heaps. La tabella dei metadati che elenca le classi contiene ad esempio riferimenti alla tabella che elenca i metodi.For example, the metadata table for classes references the table for methods.

I metadati memorizzano informazioni anche in quattro strutture heap: stringhe, blob, stringhe utente e GUID.Metadata also stores information in four heap structures: string, blob, user string, and GUID. Tutte le stringhe utilizzate per denominare i tipi e i membri sono memorizzate nell'heap delle stringhe.All the strings used to name types and members are stored in the string heap. La tabella dei metodi, ad esempio, non memorizza il nome dei metodi direttamente, ma punta al nome del metodo memorizzato nell'heap delle stringhe.For example, a method table does not directly store the name of a particular method, but points to the method's name stored in the string heap.

Token di metadatiMetadata Tokens

Ciascuna riga di ciascuna tabella dei metadati è identificata in modo univoco nella parte MSIL del file PE da un token di metadati.Each row of each metadata table is uniquely identified in the MSIL portion of the PE file by a metadata token. I token di metadati sono concettualmente simili a puntatori, memorizzati in MSIL, che fanno riferimento a una determinata tabella dei metadati.Metadata tokens are conceptually similar to pointers, persisted in MSIL, that reference a particular metadata table.

Un token di metadati è un numero a quattro byte.A metadata token is a four-byte number. Il byte più significativo indica la tabella dei metadati a cui il token fa riferimento (metodi, tipi e così via).The top byte denotes the metadata table to which a particular token refers (method, type, and so on). I rimanenti tre byte individuano la riga della tabella dei metadati che corrisponde all'elemento di programmazione che si sta descrivendo.The remaining three bytes specify the row in the metadata table that corresponds to the programming element being described. Se si definisce un metodo in C# e lo si compila in un file PE, si potrà trovare il seguente token di metadati nella parte MSIL del file PE:If you define a method in C# and compile it into a PE file, the following metadata token might exist in the MSIL portion of the PE file:

0x06000004

Il byte più significativo (0x06) indica che si tratta di un token MethodDef.The top byte (0x06) indicates that this is a MethodDef token. I tre byte meno significativi (000004) indicano a Common Language Runtime di cercare le informazioni che descrivono la definizione di questo metodo nella quarta riga della tabella MethodDef.The lower three bytes (000004) tells the common language runtime to look in the fourth row of the MethodDef table for the information that describes this method definition.

Metadati all'interno di un file PEMetadata within a PE File

Quando un programma viene compilato per Common Language Runtime, viene convertito in un file PE, costituito da tre parti.When a program is compiled for the common language runtime, it is converted to a PE file that consists of three parts. Nella tabella che segue viene descritto il contenuto di ciascuna parte.The following table describes the contents of each part.

Sezione del PEPE section ContenutoContents of PE section
Intestazione PEPE header L'indice delle sezioni principali del file PE e l'indirizzo del punto di ingresso.The index of the PE file's main sections and the address of the entry point.

Il runtime usa queste informazioni per identificare il file come file PE e per determinare da che punto iniziare l'esecuzione quando carica il programma in memoria.The runtime uses this information to identify the file as a PE file and to determine where execution starts when loading the program into memory.
Istruzioni MSILMSIL instructions Le istruzioni MSIL che costituiscono il codice.The Microsoft intermediate language instructions (MSIL) that make up your code. Molte istruzioni MSIL sono accompagnate da token di metadati.Many MSIL instructions are accompanied by metadata tokens.
MetadatiMetadata Le tabelle e gli heap dei metadati.Metadata tables and heaps. Il runtime usa questa sezione per memorizzare informazioni sui tutti i tipi e i membri presenti nel codice.The runtime uses this section to record information about every type and member in your code. Questa sezione include anche attributi personalizzati e informazioni sulla sicurezza.This section also includes custom attributes and security information.

Utilizzo dei metadati in fase di esecuzioneRun-Time Use of Metadata

Per meglio comprendere i metadati e il ruolo che essi rivestono in Common Language Runtime, può essere utile creare un piccolo programma e illustrare come i metadati ne influenzino l'esecuzione.To better understand metadata and its role in the common language runtime, it might be helpful to construct a simple program and illustrate how metadata affects its run-time life. Nell'esempio di codice che segue vengono mostrati due metodi all'interno di una classe denominata MyApp.The following code example shows two methods inside a class called MyApp. Il metodo Main è il punto di ingresso del programma, mentre il metodo Add restituisce semplicemente la somma di due argomenti integer.The Main method is the program entry point, while the Add method simply returns the sum of two integer arguments.

Public Class MyApp
   Public Shared Sub Main()
      Dim ValueOne As Integer = 10
      Dim ValueTwo As Integer = 20
      Console.WriteLine("The Value is: {0}", Add(ValueOne, ValueTwo))
   End Sub

   Public Shared Function Add(One As Integer, Two As Integer) As Integer
      Return (One + Two)
   End Function
End Class
using System;
public class MyApp
{
   public static int Main()
   {
      int ValueOne = 10;
      int ValueTwo = 20;
      Console.WriteLine("The Value is: {0}", Add(ValueOne, ValueTwo));
      return 0;
   }
   public static int Add(int One, int Two)
   {
      return (One + Two);
   }
}

Durante l'esecuzione del codice, il runtime carica il modulo in memoria e cerca questa classe nei metadati.When the code runs, the runtime loads the module into memory and consults the metadata for this class. Dopo il caricamento, il runtime compie un'analisi approfondita del flusso Microsoft Intermediate Language (MSIL) del metodo per convertirlo in veloci istruzioni macchina native.Once loaded, the runtime performs extensive analysis of the method's Microsoft intermediate language (MSIL) stream to convert it to fast native machine instructions. Il runtime consente di usare un compilatore JIT (Just-In-Time) per convertire le istruzioni MSIL in codice macchina nativo, procedendo un metodo alla volta, in base alle necessità.The runtime uses a just-in-time (JIT) compiler to convert the MSIL instructions to native machine code one method at a time as needed.

Nell'esempio che segue viene illustrata parte del codice MSIL prodotto dalla funzione Main del codice precedente.The following example shows part of the MSIL produced from the previous code's Main function. È possibile vedere il codice MSIL e i metadati di qualsiasi applicazione .NET Framework usando il disassemblatore MSIL (Ildasm.exe).You can view the MSIL and metadata from any .NET Framework application using the MSIL Disassembler (Ildasm.exe).

.entrypoint
.maxstack  3
.locals ([0] int32 ValueOne,
         [1] int32 ValueTwo,
         [2] int32 V_2,
         [3] int32 V_3)
IL_0000:  ldc.i4.s   10
IL_0002:  stloc.0
IL_0003:  ldc.i4.s   20
IL_0005:  stloc.1
IL_0006:  ldstr      "The Value is: {0}"
IL_000b:  ldloc.0
IL_000c:  ldloc.1
IL_000d:  call int32 ConsoleApplication.MyApp::Add(int32,int32) /* 06000003 */

Il compilatore JIT legge il codice MSIL dell'intero metodo, lo analizza approfonditamente, quindi genera efficienti istruzioni native corrispondenti.The JIT compiler reads the MSIL for the whole method, analyzes it thoroughly, and generates efficient native instructions for the method. All'istruzione IL_000d viene rilevato un token di metadati per il metodo Add (/* 06000003 */) e il runtime usa il token per consultare la terza riga della tabella MethodDef.At IL_000d, a metadata token for the Add method (/* 06000003 */) is encountered and the runtime uses the token to consult the third row of the MethodDef table.

Nella tabella che segue viene illustrata la parte di MethodDef a cui fa riferimento il token di metadati che descrive il metodo Add.The following table shows part of the MethodDef table referenced by the metadata token that describes the Add method. Benché questo assembly includa altre tabelle di metadati, ciascuna con i propri valori univoci, viene qui discussa solo questa tabella.While other metadata tables exist in this assembly and have their own unique values, only this table is discussed.

RigaRow RVA (Relative Virtual Address)Relative Virtual Address (RVA) ImplFlagsImplFlags FlagsFlags NameName

(punta all'heap delle stringhe)(Points to string heap.)
Firma (punta all'heap dei blob)Signature (Points to blob heap.)
11 0x000020500x00002050 ILIL

GestitoManaged
PublicPublic

ReuseSlotReuseSlot

SpecialNameSpecialName

RTSpecialNameRTSpecialName

.ctor.ctor
.ctor (costruttore).ctor (constructor)
22 0x000020580x00002058 ILIL

GestitoManaged
PublicPublic

StaticStatic

ReuseSlotReuseSlot
MainMain StringaString
3.3 0x0000208c0x0000208c ILIL

GestitoManaged
PublicPublic

StaticStatic

ReuseSlotReuseSlot
AggiuntaAdd int, int, intint, int, int

Ogni colonna della tabella contiene importanti informazioni sul codice.Each column of the table contains important information about your code. La colonna RVA consente al runtime di calcolare l'indirizzo di memoria iniziale del codice MSIL che definisce questo metodo.The RVA column allows the runtime to calculate the starting memory address of the MSIL that defines this method. Le colonne ImplFlags e Flags contengono maschere di bit che descrivono il metodo, indicando ad esempio se il metodo è pubblico o privato.The ImplFlags and Flags columns contain bitmasks that describe the method (for example, whether the method is public or private). La colonna Name indicizza il nome del metodo nell'heap delle stringhe.The Name column indexes the name of the method from the string heap. La colonna Signature indicizza la definizione della firma del metodo nell'heap dei blob.The Signature column indexes the definition of the method's signature in the blob heap.

Il runtime calcola l'indirizzo di offset desiderato dalla colonna RVA nella terza riga e restituisce tale indirizzo al compilatore JIT, che quindi procede con il nuovo indirizzo.The runtime calculates the desired offset address from the RVA column in the third row and returns this address to the JIT compiler, which then proceeds to the new address. Il compilatore JIT continua a processare il codice MSIL al nuovo indirizzo fino a quando incontra un altro token di metadati e il processo si ripete.The JIT compiler continues to process MSIL at the new address until it encounters another metadata token and the process is repeated.

Grazie ai metadati, il runtime ha accesso a tutte le informazioni necessarie per caricare il codice e convertirlo in istruzioni macchina native.Using metadata, the runtime has access to all the information it needs to load your code and process it into native machine instructions. In questo modo, i metadati consentono l'esistenza dei file autodescrittivi e, unitamente al sistema di tipi comune, l'ereditarietà tra linguaggi diversi.In this manner, metadata enables self-describing files and, together with the common type system, cross-language inheritance.

TitoloTitle DescrizioneDescription
AttributiAttributes Viene descritto come applicare attributi, scrivere attributi personalizzati e recuperare le informazioni archiviate negli attributi.Describes how to apply attributes, write custom attributes, and retrieve information that is stored in attributes.