Share via


Reflexión frente a generación de código fuente en System.Text.Json

En este artículo se explican las diferencias entre la reflexión y la generación de código fuente en relación con la serialización de System.Text.Json. También se proporcionan instrucciones sobre cómo elegir el mejor enfoque para su escenario.

Conjunto de metadatos

Para serializar o deserializar un tipo, JsonSerializer necesita información sobre cómo acceder a los miembros del tipo. JsonSerializer necesita la siguiente información:

  • Cómo acceder a los captadores de propiedades y a los campos para la serialización.
  • Cómo acceder a un constructor, a los establecedores de propiedades y a los campos para la deserialización.
  • Información sobre qué atributos se han usado para personalizar la serialización o deserialización.
  • Configuración en tiempo de ejecución de JsonSerializerOptions.

Esta información se conoce como metadatos.

Reflexión

De manera predeterminada, JsonSerializer recopila metadatos en tiempo de ejecución mediante la reflexión. Siempre que JsonSerializer tiene que serializar o deserializar un tipo por primera vez, recopila y almacena en caché estos metadatos. El proceso de recopilación de metadatos tarda tiempo y usa memoria.

Generación de origen

Como alternativa, System.Text.Json puede usar la característica de generación de origen de C# para mejorar el rendimiento, reducir el uso de memoria privada y facilitar el recorte de ensamblados, lo que reduce el tamaño de la aplicación. Además, algunas API de reflexión no se pueden usar en aplicaciones de AOT nativo, por lo que debe usar la generación de código fuente para esas aplicaciones.

La generación de código fuente se puede usar en dos modos:

  • Modo basado en metadatos

    Durante la compilación, System.Text.Json recopila la información necesaria para la serialización y genera archivos de código fuente que rellenan los metadatos del contrato JSON para los tipos solicitados.

  • Modo de optimización de serialización (ruta de acceso rápida)

    Las características de JsonSerializer que personalizan la salida de la serialización, como las directivas de nomenclatura y la conservación de referencias, conllevan una sobrecarga de rendimiento. En el modo de optimización de serialización, System.Text.Json genera código de serialización optimizado que usa Utf8JsonWriter directamente. Este código optimizado o de ruta de acceso rápida aumenta el rendimiento de la serialización.

    La deserialización de ruta de acceso rápida no está disponible actualmente. Para obtener más información, consulte la incidencia 55043 de dotnet/runtime.

La generación de código fuente para System.Text.Json requiere C# 9.0 o una versión posterior.

Comparación de características

Elija los modos de reflexión o generación de código fuente en función de las siguientes ventajas que ofrece cada uno:

Prestación Reflexión Generación de origen
(Modo basado en metadatos)
Generación de origen
(Modo de optimización de serialización)
Más sencillo de codificar. ✔️
Más sencillo de depurar. ✔️ ✔️
Admite miembros no públicos. ✔️ ✔️* ✔️*
Admite todas las personalizaciones de serialización disponibles. ✔️
Reduce el tiempo de inicio. ✔️ ✔️
Reduce el uso de memoria privada. ✔️ ✔️
Elimina la reflexión en tiempo de ejecución. ✔️ ✔️
Facilita la reducción del tamaño de la aplicación con recortes seguros. ✔️ ✔️
Aumenta el rendimiento de la serialización. ✔️

* El generador de código fuente admite algunos miembros no públicos, por ejemplo, tipos internos en el mismo ensamblado. † Los contratos de un generador de código fuente se pueden modificar mediante la API de personalización de contratos.

Prestación Reflexión Generación de origen
(Modo basado en metadatos)
Generación de origen
(Modo de optimización de serialización)
Más sencillo de codificar. ✔️
Más sencillo de depurar. ✔️
Admite descriptores de acceso no públicos. ✔️
Admite las propiedades necesarias. ✔️
Admite propiedades de solo inicialización. ✔️
Reduce el tiempo de inicio. ✔️ ✔️
Reduce el uso de memoria privada. ✔️ ✔️
Elimina la reflexión en tiempo de ejecución. ✔️ ✔️
Facilita la reducción del tamaño de la aplicación con recortes seguros. ✔️ ✔️
Aumenta el rendimiento de la serialización. ✔️