2012-04-04 10 views
12

Duplicar posible:
How to serialize an IList<T>?cómo serializar una interfaz como IList <T>

Deseo serializar una clase (vamos a llamarlo S) que contiene una propiedad del tipo IList<T> donde T es otra clase que he definido. Obtengo una excepción cuando intenté serializar una instancia de la clase S en XML. Esto es comprensible ya que el XmlSerializer no sabe qué clase concreta usar. ¿Hay alguna forma, esperemos que utilizando atributos, para especificar qué clase concreta instanciar al serializar/deserializar una instancia? Mi implementación de la clase S crea una instancia de la clase List<T>. Aquí hay un código para ilustrar mi ejemplo:

using System; 
using System.Xml.Serialization; 
using System.IO; 

[Serializable] 
public class T { } 

[Serializable] 
public class S 
{ 
    public IList<T> ListOfTs { get; set; } 

    public S() 
    { 
     ListOfTs = new List<T>(); 
    } 
} 

public class Program 
{ 
    public void Main() 
    { 
     S s = new S(); 
     s.ListOfTs.Add(new T()); 
     s.ListOfTs.Add(new T()); 
     XmlSerializer serializer = new XmlSerializer(typeof(S)); 
     serializer.Serialize(new StringWriter(), s); 
    } 
} 

Estoy esperando que hay un atributo que puedo colocar por encima de la definición ListOfTs que dice a la serialización, "asumir una instancia de List<T> al serializar/deserializar".

Respuesta

11

Cambiar el

public IList<T> ListOfTs { get; set; } 

a

public List<T> ListOfTs { get; set; } 

después trabajará.

+3

Me gustaría hacer esto, excepto que esta iba a cambiar la interfaz de la clase 'S '. Si bien esto es poco probable que tenga efectos prácticos, pero desde el punto de principio, me gustaría ver si hay una manera de resolver el problema sin cambiar el tipo. –

+0

La solución propuesta, aunque es el que trabaja, puede arruinar su arquitectura API pública – bashis

0

Usted puede implementar la interfaz IXmlSerializable e implementar la lógica de la serialización de forma manual utilizando lectores de XML y escritores.

2

Creo que hay 2 formas que generalmente se acercaron para este tipo de problema.

Uno sería usar DataContractSerializer, pero como ya está usando XmlSerializer, probablemente no quiera hacer eso.

La "alternativa" es tener una propiedad que se utiliza específicamente para el propósito de la serialización, e ignorar el IList durante la serialización.

[Serializable] 
public class S 
{ 
    IList<T> _listofTs; 

    [XmlIgnore] 
    public IList<T> ListOfTs { get _listofTs; set _listofTs = value; } 

    [XmlElement(Name="Not Exactly the Greatest Solution!")] 
    public List<T> ListOfTs { get _listofTs; set _listofTs = value; } 

    public S() 
    { 
     ListOfTs = new List<T>(); 
    } 
} 
+0

El uso de atributos XmlIgnore en una propiedad va a ignorar totalmente. La pregunta es incluir la propiedad de interfaz en la serialización. –

Cuestiones relacionadas