Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La generación de origen se puede usar en dos modos: optimización basada en metadatos y serialización. En este artículo se describen los distintos modos.
Para obtener información sobre cómo usar los modos de generación de origen, vea Uso de la generación de origen en System.Text.Json.
Modo basado en metadatos
Puede usar la generación de origen para mover el proceso de recopilación de metadatos del tiempo de ejecución al tiempo de compilación. Durante la compilación se recopilan metadatos y se generan archivos de código fuente. Los archivos de código fuente generados se compilan automáticamente como parte integral de la aplicación. Esta técnica elimina la recopilación de metadatos en tiempo de ejecución, lo que mejora el rendimiento de la serialización y la deserialización.
Las mejoras de rendimiento proporcionadas por la generación de origen pueden ser considerables. Por ejemplo, los resultados de las pruebas han mostrado hasta un 40 % o más de reducción del tiempo de inicio, de reducción de memoria privada, de aumento de la velocidad de rendimiento (en modo de optimización de serialización) y de reducción del tamaño de la aplicación.
Constructores y miembros no públicos
De forma predeterminada, tanto el modo de reflexión como el modo de generación de código fuente incluyen únicamente propiedades y campos public en el contrato de serialización.
A partir de .NET 11, la generación de código fuente admite miembros que se marquen explícitamente con el atributo [JsonInclude]. El miembro puede ser private, internalo protected. También admite accesores private, internal y protected en propiedades marcadas con [JsonInclude]. La generación de origen también admite constructores inaccesibles marcados con [JsonConstructor].
En .NET 11, los descriptores de acceso generados usan UnsafeAccessorAttribute.
Un setter generado a partir del código fuente para una propiedad de solo init se ejecuta solo cuando la carga útil JSON contiene esa propiedad. Una propiedad init exclusiva que la carga útil omite conserva el valor de su inicializador de propiedad.
En .NET 10 y versiones anteriores, la generación de origen tiene las siguientes limitaciones:
- La generación de código fuente no admite miembros ni descriptores de acceso
privateoprotected. Si se marca un miembro de este tipo con[JsonInclude], el serializador lanza una excepción NotSupportedException en tiempo de ejecución. - La generación de código fuente admite miembros y descriptores de acceso
internalsolo cuando son accesibles para el JsonSerializerContext generado en el mismo ensamblado. - La generación de origen no admite constructores inaccesibles para el contexto generado, incluso cuando se marcan con
[JsonConstructor].
Problemas conocidos
Para obtener información sobre otros problemas conocidos de la generación de origen, vea los problemas de GitHub etiquetados como "source-generator" en el repositorio dotnet/runtime.
Modo de optimización de serialización (ruta de acceso rápida)
JsonSerializer tiene muchas características que personalizan la salida de la serialización, como las directivas de nomenclatura y la conservación de referencias. La compatibilidad con todas esas características provoca cierta sobrecarga de rendimiento. La generación de código fuente puede mejorar el rendimiento de la serialización mediante la generación de código optimizado que usa Utf8JsonWriter directamente.
El modo de optimización de serialización emite métodos de serialización de ruta rápida, pero no metadatos de serialización. La serialización de ruta rápida está restringida en lo que puede hacer; no admite la serialización asincrónica ni ningún modo de deserialización.
Además, el código optimizado no admite todas las características de serialización que JsonSerializer admite. El serializador detecta si se puede usar el código optimizado y recurre al código de serialización predeterminado si se especifican opciones no admitidas. Por ejemplo, JsonNumberHandling.AllowReadingFromString no es aplicable a la escritura, por lo que la especificación de esta opción no hace que se recurra al código predeterminado.
En la tabla siguiente se muestran las opciones de JsonSerializerOptions compatibles con la serialización de ruta de acceso rápido:
| Opción de serialización | Compatible con la ruta de acceso rápida |
|---|---|
| AllowTrailingCommas | ✔️ |
| Converters | ❌ |
| DefaultBufferSize | ✔️ |
| DefaultIgnoreCondition | ✔️ |
| DictionaryKeyPolicy | ❌ |
| Encoder | ❌ |
| IgnoreNullValues | ❌ |
| IgnoreReadOnlyFields | ✔️ |
| IgnoreReadOnlyProperties | ✔️ |
| IncludeFields | ✔️ |
| MaxDepth | ✔️ |
| NumberHandling | ❌ |
| PropertyNamingPolicy | ✔️ |
| ReferenceHandler | ❌ |
| TypeInfoResolver | ✔️ |
| WriteIndented | ✔️ |
(No se admiten las siguientes opciones porque solo se aplican a la deserialización: PropertyNameCaseInsensitive, ReadCommentHandling y UnknownTypeHandling).
En la siguiente tabla se muestran los atributos admitidos por la serialización rápida:
| Atributo | Compatible con la ruta de acceso rápida |
|---|---|
| JsonConstructorAttribute | ❌ |
| JsonConverterAttribute | ❌ |
| JsonDerivedTypeAttribute | ✔️ |
| JsonExtensionDataAttribute | ❌ |
| JsonIgnoreAttribute | ✔️ |
| JsonIncludeAttribute | ✔️ |
| JsonNumberHandlingAttribute | ❌ |
| JsonPolymorphicAttribute | ✔️ |
| JsonPropertyNameAttribute | ✔️ |
| JsonPropertyOrderAttribute | ✔️ |
| JsonRequiredAttribute | ✔️ |
Si se especifica una opción o atributo no compatible para un tipo, el serializador vuelve al modo de metadatos, suponiendo que el generador de origen se haya configurado para generar metadatos. En ese caso, el código optimizado no se usa al serializar ese tipo, pero podría usarse para otros tipos. Por lo tanto, es importante realizar pruebas de rendimiento con las opciones y cargas de trabajo para determinar cómo de ventajoso resulta en realidad el modo de optimización de serialización. Además, la capacidad de revertir al JsonSerializer código requiere el modo de metadatos. Si selecciona solo el modo de optimización de serialización, es posible que se produzca un error en la serialización de tipos u opciones que necesiten recurrir al código JsonSerializer.