Scenari relativi a metodi dinamici della reflection emit

I metodi dinamici creati utilizzando la classe DynamicMethod, una novità di .NET Framework versione 2.0, forniscono funzionalità ottimizzate per creare metodi statici in fase di esecuzione. I metodi dinamici aumentano la funzionalità dei tipi presenti nello spazio dei nomi System.Reflection.Emit in diversi modi:

  • Presentano un sovraccarico ridotto perché non è necessario generare assembly, moduli e tipi dinamici per contenere i metodi.

  • Nelle applicazioni a esecuzione prolungata consentono un utilizzo ottimale delle risorse grazie alla possibilità di recuperare la memoria utilizzata dal corpo di un metodo quando quest'ultimo non è più necessario.

  • Se sono disponibili autorizzazioni di sicurezza sufficienti, forniscono la possibilità di associare il codice a un assembly o a un tipo esistente. Tale codice avrà la stessa visibilità dei membri privati o dei tipi interni.

  • Se sono disponibili autorizzazioni di sicurezza sufficienti, consentono al codice di ignorare i controlli di visibilità JIT e accedere ai dati privati e protetti degli oggetti.

I metodi dinamici possono utilizzare un oggetto ILGenerator per creare codice MSIL (Microsoft Intermediate Language), nonché un oggetto DynamicILInfo per operare su ambiti e token di metadati che consentono a client avanzati di generare codice MSIL specifico.

I metodi dinamici risultano utili negli scenari in cui è necessario generare codice in fase di esecuzione per motivi di prestazioni. Gli esempi illustrati in questa sezione includono serializzazione, mapping tra oggetti e database relazionali, espressioni regolari, valutazioni parziali e compilatori per linguaggi che richiedono runtime.

Per un esempio semplice di generazione di metodi dinamici, vedere Procedura: definire ed eseguire metodi dinamici.

Linguaggi che supportano chiamate con associazione tardiva

I metodi dinamici sono utili per i writer del compilatore quando il tipo di un oggetto non è noto in fase di compilazione. Le chiamate ai membri dell'oggetto devono essere risolte in fase di esecuzione, in genere con il sovraccarico aggiuntivo di elenchi di argomenti di modifica. Nel codice Visual Basic riportato di seguito viene fornito un esempio al riguardo.

Sub Example(ByVal obj as Object)
    ' ...
    obj.SomeMethod(x, y, z)
    ' ...
End Sub

Il compilatore deve generare codice per cercare SomeMethod, disporre gli argomenti sotto forma di matrice di oggetti e richiamare il metodo. L'esecuzione di tali chiamate con la reflection, utilizzando il metodo InvokeMember, non garantisce prestazioni ottimali. Le prestazioni possono essere migliorate utilizzando i membri dello spazio dei nomi System.Reflection.Emit per creare un metodo, un tipo, un modulo e un assembly dinamici. È tuttavia possibile che questa operazione estenda eccessivamente l'insieme di lavoro e aumenti la complessità del codice. I metodi dinamici forniscono una strategia di implementazione più efficiente nei casi in cui la firma del metodo dinamico corrisponde a un tipo delegato esistente, poiché non è necessario creare un tipo, un modulo o un assembly dinamico. Questo approccio offre prestazioni significativamente migliori rispetto all'utilizzo del metodo InvokeMember. Anche se non funziona allo stesso livello di una chiamata virtuale, richiede un insieme di lavoro più contenuto perché non è necessario creare nuovi tipi. Infine, il codice MSIL generato e il codice nativo associato possono essere rilasciati quando non sono più necessari.

Serializzazione

I metodi dinamici rendono superflua la scrittura di codice di serializzazione e deserializzazione. È possibile contrassegnare un tipo serializzabile in base a semplici regole, quindi utilizzare un motore di serializzazione per esaminare i metadati relativi al tipo, creare un serializzatore e un deserializzatore appropriati a specifiche esigenze ed eseguire il codice generato in istanze del tipo.

Se sono disponibili autorizzazioni di sicurezza sufficienti, un motore di serializzazione implementato tramite metodi dinamici può accedere ai dati privati e protetti per attivare la serializzazione di oggetti non generati dal creatore del motore.

I metodi generati possono essere memorizzati nella cache, se utilizzati di frequente, oppure semplicemente rilasciati.

Valutazione parziale

La valutazione parziale, nota anche come specializzazione di programma, è una tecnica che consente di ottimizzare gli algoritmi nei casi in cui una o più variabili di input variano più lentamente degli altri input. La valutazione parziale genera chiamate a metodi specializzati in cui i valori degli input che variano lentamente vengono considerati costanti, consentendo l'applicazione di ottimizzazioni aggiuntive all'intero algoritmo.

Grazie a questa tecnica, è spesso possibile trasformare un algoritmo generale a basse prestazioni in un algoritmo specializzato ad alte prestazioni. Di seguito vengono forniti alcuni esempi:

  • Compilazione di un oggetto Regex per la generazione di un programma specializzato per corrispondere a un modello specifico.

  • Compilazione di un motore di serializzazione guidato dai metadati all'interno di un programma specializzato per eseguire la serializzazione e la deserializzazione di un tipo specifico o di un insieme di tipi.

  • Compilazione di uno schema XML per la generazione di un programma specializzato per convalidare uno schema specifico.

  • Compilazione di una trasformazione XSLT all'interno di un programma specializzato per trasformare un documento XML in modo specifico.

  • Compilazione di un programma di crittografia generico che crittografa i dati utilizzando una qualsiasi chiave specificata in un programma ottimizzato per una chiave specifica.

I metodi dinamici possono essere utilizzati per implementare la valutazione parziale generando metodi specializzati in fase di esecuzione. Oltre al miglioramento delle prestazioni, i metodi dinamici consentono il rilascio dei corpi dei metodi MSIL e del codice macchina corrispondente generato dal compilatore JIT. Nei programmi a esecuzione prolungata questa possibilità può rivelarsi cruciale.

Per una descrizione più dettagliata di alcuni di questi scenari, vedere Scenari di applicazioni della reflection emit.

Generazione di codice utente personalizzato in fase di esecuzione

Numerose applicazioni o piattaforme sono dotate di meccanismi di estensibilità che offrono agli utenti la possibilità di scrivere ed eseguire codice personalizzato durante l'esecuzione dell'applicazione, in genere tramite l'utilizzo di funzioni predefinite. Utilizzando i metodi dinamici per la generazione di questo codice, lo sviluppatore della piattaforma o dell'applicazione sarà in grado di ridurre il numero delle funzioni necessarie, quindi delle impronte della memoria, nonché di fornire più flessibilità all'utente senza compromettere le prestazioni.

Vedere anche

Attività

Procedura: definire ed eseguire metodi dinamici

Riferimenti

DynamicMethod

Concetti

Scenari di applicazioni della reflection emit

Altre risorse

Creazione di assembly e metodi dinamici