.NET XML serialización y herencia

Tengo una estructura como esta:

public interface A { public void method(); } public class B : A { } public class C : A { } List list; 

La lista contiene objetos de tipo B y C, también tienen algunos campos que me gustaría conservar, ¿puedo ahora serializarlos, deserializarlos y obtener las instancias de objetos adecuadas? Preferiblemente a XML

EDITAR:

¿Hay alguna forma sencilla de serializar esta lista que contenga interfaces y luego deserializarla de nuevo a las instancias B y C?

Suponiendo que esté utilizando la serialización .net XML incorporada, debería echar un vistazo al siguiente atributo:

 System.Xml.Serialization.XmlIncludeAttribute 

Le permite indicar al serializador que incluya otros tipos al serializar / deserializar.

Agregar nuevos tipos a la lista y no actualizar los metadatos de serialización es una fuente común de errores, asegúrese de tener una cobertura de prueba adecuada.

Usaría una clase abstracta en lugar de una interfaz (ya que no se puede serializar un tipo de interfaz), luego, en lugar de codificar el tipo usando el atributo XmlInclude, agregaría los tipos conocidos al XmlSerializer en los métodos Serial y Deserializar como tal. :

  string listXml = Serialize>(ListA, new Type[] { typeof(B), typeof(C) }); List NewList = Deserialize>(listXml, new Type[] { typeof(B), typeof(C) }); private static T Deserialize(string Xml, Type[] KnownTypes) { XmlSerializer xs = new XmlSerializer(typeof(T),KnownTypes); StringReader sr = new StringReader(Xml); return (T)xs.Deserialize(sr); } private static string Serialize(Object obj, Type[] KnownTypes) { StringBuilder sb = new StringBuilder(); using (StringWriter sw = new StringWriter(sb)) { XmlSerializer xs = new XmlSerializer(typeof(T), KnownTypes); xs.Serialize(sw, obj); } return sb.ToString(); } 

Sí, pero tienes que jugar con los atributos XmlElement, XmlRoot y XmlArray. Cada tipo necesita su propio nombre de elemento.

EDIT: Algún código de ejemplo. Todas las clases se derivan de una clase base común.

Aquí hay un código de ejemplo:

 [XmlRoot(ElementName="Root")] public sealed class SomeObject { private BaseObject _Object; [XmlElement(Type=typeof(App.Projekte.Projekt), ElementName="Projekt")] [XmlElement(Type=typeof(App.Projekte.Task), ElementName="Task")] [XmlElement(Type=typeof(App.Projekte.Mitarbeiter), ElementName="Mitarbeiter")] public BaseObject Object { get { return _Object; } set { _Object = value; } } } 

EDITAR: eliminar el atributo de serialización ya que no es necesario (pero es necesario en mi proyecto de donde proviene el código)

Para su caso, haga una clase abstracta que implemente su interfaz como:

 abstract class Abs : A 

y luego derivar sus clases de Abs

 public class B : Abs public class C : Abs 

y lista de lista;

ahora use XmlIncludeAttribute para agregar sus tipos a la matriz de tipos del XmlSerializer.

XmlSerializer no funciona con interfaces. Así que puedes:

Convierta la interfaz en clase abstracta y luego use XmlIncludeAttribute para ella o proporcione KnownTypes a XmlSerializer

o

Implementar IXmlSerializable para el tipo padre

o

Considere usar DataContractSerializer desde .NET 3.0