2011-06-30 20 views
7

Tengo algunas clases de contenedor que exponen sus colecciones a través de ReadOnlyCollection. Se proporcionan métodos personalizados para agregar y eliminar de la colección que también realizan alguna lógica personalizada.Xml Serialización de ReadOnlyCollections

Por ejemplo:

public class Foo 
{ 
    List<Bar> _barList = new List<Bar>(); 

    public ReadOnlyCollection<Bar> BarList 
    { 
     get { return _barList.AsReadOnly(); } 
    } 

    public void AddBar(Bar bar) 
    { 
     if (bar.Value > 10) 
      _barList.Add(bar); 
     else 
      MessageBox.Show("Cannot add to Foo. The value of Bar is too high"); 
    } 
    public void RemoveBar(Bar bar) 
    { 
     _barList.Remove(bar); 
     // Foo.DoSomeOtherStuff(); 
    } 

} 

public class Bar 
{ 
    public string Name { get; set; } 
    public int Value { get; set; } 
} 

Esto es todo muy bien, pero cuando llego a serializar Foo con el serializador XML se genera una excepción.

¿Alguien puede ofrecer una buena manera de solucionar esto?

Gracias

+0

¿Cuál es la excepción? –

+1

Lanza una InvalidOperationException debido a un error al reflejar Foo. –

Respuesta

2

No se puede deserializar ReadOnlyCollection porque no tiene Add método. Para el montaje de que el uso de una segunda propiedad para la serialización:

[XmlIgnore()] 
public ReadOnlyCollection<Bar> BarList 
{ 
    get { return _barList.AsReadOnly(); } 
} 

[Browsable(false)] 
[EditorBrowsable(EditorBrowsableState.Never)] 
[DebuggerBrowsable(DebuggerBrowsableState.Never)] 
//[Obsolete("This is only for serialization process", true)] 
[XmlArray("BarList")] 
[XmlArrayItem("Bar")] 
public List<Bar> XmlBarList 
{ 
    get { return _barList; } 
    set { _barList = value; } 
} 
+2

Creo que las propiedades que están marcadas como obsoletas, tampoco se serializan ... –

+1

@Frederik: simplemente pruébalo y descubre que tienes razón. las propiedades 'Obsolete' no serán serializadas. Gracias por el comentario y lo siento por mi _insistencia_ que lo hace .. –

+0

Hola, gracias por la respuesta, también estoy descubriendo que agregar la etiqueta obsoleta impide la serialización –

4

De hecho, eso no funcionará. Entonces no hagas eso. Además, no hay ganchos para detectar la serialización xml, excepto el tan doloroso IXmlSerializable.

Así que o bien:

  • no utilice una colección de sólo lectura aquí
  • IXmlSerializable implemento (complicado)
  • tienen una API doble (uno de sólo lectura, no; serializar el " no" - XmlSerializer complicado, ya que sólo se encarga de los miembros publicx)
  • utilizar un DTO separada para la serialización