La clase JsonSerializerOptions tiene la siguiente propiedad:
public IList<Serialization.JsonConverter> Converters { get; }Este código funciona bien, como se esperaba:
using System.Text.Json.Serialization; var options = new JsonSerializerOptions(); options.Converters.Add(new JsonStringEnumConverter());Este código falla, como se esperaba:
var options = new JsonSerializerOptions { Converters = new List<JsonConverter> { new JsonStringEnumConverter() } }; // `Property or indexer 'JsonSerializerOptions.Converters' cannot be assigned to -- it is read only`Hasta aquí todo bien. Pero este código también funciona bien, para mi sorpresa:
var options = new JsonSerializerOptions { Converters = { new JsonStringEnumConverter() } }; ¿Qué está pasando exactamente en ese último ejemplo? Puede que esté teniendo un lapso mental, pero no creo que haya encontrado tal sintaxis antes. ¿Alguien puede señalar dónde está documentado? Y no entiendo por qué es capaz de eludir la falta de set o init de la propiedad.
Nota al margen: el código sobre el que pregunto se basó en este artículo .
¿Qué está pasando exactamente en ese último ejemplo? Puede que esté teniendo un lapso mental, pero no creo que haya encontrado tal sintaxis antes. ¿Alguien puede señalar dónde está documentado?
Es la sintaxis del inicializador de la colección. Está documentado aquí . Y más directamente con respecto a los accesorios de solo lectura aquí .
Algunas clases pueden tener propiedades de colección donde la propiedad es de solo lectura... No podrá usar la sintaxis del inicializador de colección discutida hasta ahora ya que no se puede asignar una nueva lista a la propiedad. Sin embargo, se pueden agregar nuevas entradas utilizando la sintaxis de inicialización al omitir la creación de la lista.
Esta sintaxis funciona para "tipos de colección que implementan IEnumerable y tiene Add con la firma adecuada como método de instancia o método de extensión".
Para una lectura más profunda, eche un vistazo a la especificación donde dice con mayor precisión:
El objeto de colección al que se aplica un inicializador de colección debe ser de un tipo que implemente
System.Collections.IEnumerableo se producirá un error en tiempo de compilación. Para cada elemento especificado en orden, se aplica la búsqueda normal de miembros para encontrar un miembro llamadoAdd. Si el resultado de la búsqueda de miembros no es un grupo de métodos, se produce un error en tiempo de compilación. De lo contrario, la resolución de sobrecarga se aplica con la lista de expresiones del inicializador de elementos como lista de argumentos y el inicializador de la colección invoca el método resultante. Por lo tanto, el objeto de colección contendrá una instancia aplicable o un método de extensión con el nombreAddpara cada inicializador de elemento.
Es una sintaxis muy oscura que existe en C#, pero no mucha gente la conoce.
El código del último ejemplo es en realidad equivalente a:
var options = new JsonSerializerOptions(); options.Converters.Add(new JsonStringEnumConverter()); No se asigna a la propiedad Converters , sino que solo inserta los valores en la lista.