Condividi tramite


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.