Reflexão x geração de código-fonte em System.Text.Json
Este artigo explica as diferenças entre a reflexão e a geração de código-fonte no que diz respeito à serialização do System.Text.Json
. Também fornece diretrizes sobre como escolher a melhor abordagem para a sua conjuntura.
Coleção de metadados
Para serializar ou desserializar um tipo, JsonSerializer precisa de informações sobre como acessar os membros do tipo. JsonSerializer
precisa das seguintes informações:
- Como acessar getters e campos de propriedade para serialização.
- Como acessar um construtor, setters de propriedades e campos para desserialização.
- Informações sobre quais atributos foram usados para customizar a serialização ou desserialização.
- Configuração de tempo de execução de JsonSerializerOptions.
Essas informações são chamadas de metadados.
Reflexão
Por padrão, JsonSerializer coleta metadados em tempo de execução usando reflexão. Sempre que JsonSerializer
tiver que serializar ou desserializar um tipo pela primeira vez, ele coleta e armazena em cache esses metadados. O processo de coleta de metadados leva tempo e usa memória.
Geração de origem
Como alternativa, System.Text.Json
pode usar o recurso de geração de origem C# para melhorar o desempenho, reduzir o uso de memória privada e facilitar o corte do assembly, o que reduz o tamanho do aplicativo. Além disso, determinadas APIs de reflexão não podem ser usadas em aplicativos nativos de AOT e, portanto, você precisa usar geração de código-fonte para esses aplicativos.
A geração de código-fonte pode ser usada em dois modos:
Modo baseado em metadados
Durante a compilação, o
System.Text.Json
coleta as informações necessárias para a serialização e gera arquivos de código-fonte que preenchem os metadados de contrato JSON para os tipos solicitados.Modo serialização-otimização (expressa)
Os recursos de JsonSerializer que personalizam a saída da serialização, como políticas de nomenclatura e preservação de referências, implicam uma sobrecarga de desempenho. No modo serialização-otimização, o System.Text.Json gera um código de serialização otimizado que usa o
Utf8JsonWriter
diretamente. Esse código expresso ou otimizado aumenta a taxa de transferência da serialização.A desserialização expressa não está disponível no momento. Para obter mais informações, confira problema de dotnet/runtime 55043.
A geração de código-fonte para o System.Text.Json
requer o C# versão 9.0 ou posterior.
Comparação de recursos
Escolha os modos de reflexão ou geração de código-fonte com base nos seguintes benefícios que cada um oferece:
Benefício | Reflexão | Geração de origem (Modo baseado em metadados) |
Geração de origem (Modo serialização-otimização) |
---|---|---|---|
Mais simples para codificar. | ✔️ | ❌ | ❌ |
Mais simples para depurar. | ❌ | ✔️ | ✔️ |
Compatível com membros não públicos. | ✔️ | ✔️* | ✔️* |
Suporta todas as personalizações de serialização disponíveis. | ✔️ | ❌† | ❌† |
Reduz o tempo de inicialização. | ❌ | ✔️ | ✔️ |
Reduz o uso de memória privada. | ❌ | ✔️ | ✔️ |
Elimina a reflexão em tempo de execução. | ❌ | ✔️ | ✔️ |
Facilita a redução do tamanho do aplicativo com segurança de corte. | ❌ | ✔️ | ✔️ |
Aumenta a taxa de transferência de serialização. | ❌ | ❌ | ✔️ |
* O gerador de código-fonte é compatível com alguns membros não públicos, como, por exemplo, tipos internos no mesmo assembly. † Os contratos gerados por código-fonte podem ser modificados usando a API de personalização de contratos.