Pregunta

Tengo una clase que estoy usando como una clase de configuración que se serializa en un archivo XML que los administradores pueden editar para cambiar la configuración en la aplicación. (La configuración es un poco más compleja de lo que permite App.config).

Estoy usando la clase XmlSerializer para deserializar el archivo XML, y quiero que pueda configurar la clase de propiedad, pero no quiero que otros desarrolladores que usan la clase / ensamblaje puedan configurar / cambiar la propiedad a través del código. ¿Puedo hacer que esto suceda con la clase XmlSerializer?

Para agregar algunos detalles más: esta clase en particular es una colección y, según FxCop, la clase XmlSerializer tiene un soporte especial para deserializar colecciones de solo lectura, pero no he podido encontrar más información al respecto. Los detalles exactos sobre la regla que esto viola son:

  

Las propiedades que devuelven colecciones deben ser de solo lectura para que los usuarios no puedan reemplazar por completo el almacén de respaldo. Los usuarios aún pueden modificar el contenido de la colección llamando a métodos relevantes en la colección. Tenga en cuenta que la clase XmlSerializer tiene un soporte especial para deserializar colecciones de solo lectura. Consulte la descripción general de XmlSerializer para obtener más información.

Esto es exactamente lo que quiero, pero ¿cómo lo hago?

Editar: OK, creo que me estoy volviendo un poco loco aquí. En mi caso, todo lo que tenía que hacer era inicializar el objeto Colección en el constructor y luego eliminar el configurador de propiedades. Entonces, el objeto XmlSerializable sabe usar las propiedades Add / AddRange e indexador en el objeto Collection. ¡Lo siguiente realmente funciona!

public class MySettings
{
    private Collection<MySubSettings> _subSettings;
    public MySettings()
    {
       _subSettings = new Collection<MySubSettings>();
    }

    public Collection<MySubSettings> SubSettings
    {
         get { return _subSettings; }
    }
}
¿Fue útil?

Solución

Debe usar un tipo de lista mutable, como ArrayList (o IList IIRC).

Otros consejos

@Rob Cooper tenía razón, simplemente implementa La interfaz ISerializable y usted podrá tener un control personalizado sobre cómo su clase se serializa y deserializa y establece los campos manualmente. Es un poco más de trabajo de piernas pero logrará el objetivo deseado. Buena suerte.

No creo que pueda usar la serialización automática ya que la propiedad es de solo lectura.

Mi curso de acción sería implementar ISerializable y hágalo manualmente. Podrá establecer los valores internos desde aquí.

Sin embargo, si sus subobjetos (que se exponen como solo lectura) pueden ser capaces de ser serializados, todo debería funcionar ...

Creo que la regla de la que se queja FxCop es que tienes algo como:

public List<MyObject> Collection
{
   get { return _collection; }
   set { _collection = value; }
}

¿No es así? Si no, ¿puedes pegar un código para que pueda ver qué estás haciendo exactamente? Hay varias formas de hacer todo lo anterior :)

La respuesta de @ leppie fue en realidad la más cercana. Este es el texto relevante actual en la documentación de XmlSerializer y vea mi edición en la pregunta anterior para obtener más detalles:

  

El XmlSerializer da un tratamiento especial a las clases que implementan IEnumerable o ICollection. Una clase que implementa IEnumerable debe implementar un método Add público que toma un solo parámetro. El parámetro del método Add debe ser del mismo tipo que el devuelto por la propiedad Current en el valor devuelto por GetEnumerator, o una de las bases de ese tipo. Una clase que implementa ICollection (como CollectionBase) además de IEnumerable debe tener una propiedad indexada Item pública (indexador en C #) que toma un número entero, y debe tener una propiedad Count pública de tipo entero. El parámetro del método Agregar debe ser del mismo tipo que se devuelve de la propiedad Item o una de las bases de ese tipo. Para las clases que implementan ICollection, los valores que se serializan se recuperan de la propiedad Item indexada, no llamando a GetEnumerator.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top