Reflection e generazione di origini in System.Text.Json
Questo articolo illustra le differenze tra reflection e la generazione di origine in relazione alla serializzazione System.Text.Json
. Fornisce inoltre indicazioni su come scegliere l'approccio migliore per lo scenario.
Raccolta di metadati
Per serializzare o deserializzare un tipo, JsonSerializer necessita informazioni su come accedere ai membri del tipo. JsonSerializer
necessita delle informazioni seguenti:
- Come accedere ai getter e ai campi delle proprietà per la serializzazione.
- Come accedere a un costruttore, a setter di proprietà e ai campi per la deserializzazione.
- Informazioni sugli attributi usati per personalizzare la serializzazione o la deserializzazione.
- Configurazione del runtime da JsonSerializerOptions.
Queste informazioni vengono definite metadati.
Riflessione
Per impostazione predefinita, JsonSerializer raccoglie i metadati in fase di esecuzione usando reflection. Ogni volta che JsonSerializer
deve serializzare o deserializzare un tipo per la prima volta, raccoglie e memorizza nella cache questi metadati. Il processo di raccolta dei metadati richiede tempo e l’uso della memoria.
Generazione di origine
In alternativa, System.Text.Json
può usare la funzionalità di generazione dell'origine di C# per migliorare le prestazioni, ridurre l'utilizzo della memoria privata e facilitare il taglio dell'assembly, riducendo così le dimensioni dell'app. Inoltre, alcune API di reflection non possono essere usate nelle applicazioni AOT native, quindi è necessario usare la generazione di origine per tali app.
La generazione di origine può essere usata in due modalità:
Modalità basata su metadati
Durante la compilazione,
System.Text.Json
raccoglie le informazioni necessarie per la serializzazione e genera file di codice sorgente che popolano i metadati del contratto JSON per i tipi richiesti.Modalità Ottimizzazione della serializzazione (percorso rapido)
Funzionalità JsonSerializer che personalizzano l'output della serializzazione, ad esempio i criteri di denominazione e la conservazione dei riferimenti, comportano un sovraccarico delle prestazioni. Nella modalità di ottimizzazione della serializzazione, System.Text.Json genera codice di serializzazione ottimizzato che usa
Utf8JsonWriter
direttamente. Questo codice ottimizzato o di percorso rapido aumenta la velocità effettiva di serializzazione.Il percorso rapido deserializzazione attualmente non è disponibile. Per altre informazioni, vedere Problema 55043 per dotnet/runtime.
La generazione di origine per System.Text.Json
richiede C# 9.0 o una versione successiva.
Confronto delle funzionalità
Scegliere le modalità di reflection o generazione dell’origine in base ai vantaggi seguenti offerti da ognuno di essi:
Vantaggio | Riflessione | Generazione di origine (modalità basata su metadati) |
Generazione di origine (Modalità di ottimizzazione della serializzazione) |
---|---|---|---|
Più semplice da codificare. | ✔️ | ❌ | ❌ |
Più semplice per eseguire il debug. | ❌ | ✔️ | ✔️ |
Supporta membri non pubblici. | ✔️ | ✔️* | ✔️* |
Supporta tutte le personalizzazioni di serializzazione disponibili. | ✔️ | ❌† | ❌† |
Riduce il tempo di avvio. | ❌ | ✔️ | ✔️ |
Riduce l'utilizzo della memoria privata. | ❌ | ✔️ | ✔️ |
Elimina la reflection in fase di esecuzione. | ❌ | ✔️ | ✔️ |
Facilita la riduzione delle dimensioni delle app in modo sicuro. | ❌ | ✔️ | ✔️ |
Aumenta la velocità effettiva di serializzazione. | ❌ | ❌ | ✔️ |
* Il generatore di origine supporta alcuni membri non pubblici, ad esempio tipi interni nello stesso assembly. † contratti generati dall'origine possono essere modificati usando l'API di personalizzazione del contratto.