2012-01-13 11 views
10

Editar Este código debe ilustrar el problema:¿Por qué XmlSerializer serializa clases abstractas pero no interfaces?

[XmlInclude(typeof(AThing1))] 
public abstract class AThing 
{ 
    public abstract string Name { get; set; } 
} 

[XmlInclude(typeof(IThing1))] 
public interface IThing 
{ 
    string Name { get; set; } 
} 

public class AThing1 : AThing 
{ 
    public override string Name { get; set; } 
} 

public class IThing1 : IThing 
{ 
    public string Name { get; set; } 
} 

List<AThing> aThings = new List<AThing>(new AThing[] { new AThing1() { Name = "Bob" } }); 
List<IThing> iThings = new List<IThing>(new IThing[] { new IThing1() { Name = "Bob" } }); 

public void Test() 
{ 
    using (StringWriter sw = new StringWriter()) 
    { 
     XmlSerializer aSerializer = new XmlSerializer(typeof(List<AThing>)); 
     aSerializer.Serialize(sw, aThings); 
     string text = sw.ToString(); 
    } 

    using (StringWriter sw = new StringWriter()) 
    { 
     // This line will throw "Cannot serialize interface IThing.": 
     XmlSerializer iSerializer = new XmlSerializer(typeof(List<IThing>));  
     iSerializer.Serialize(sw, iThings); 
     string text = sw.ToString(); 
    } 
} 

La primera text generada por aSerializer será:

<?xml version="1.0" encoding="utf-16"?> 
<ArrayOfAThing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <AThing xsi:type="AThing1"> 
    <Name>Bob</Name> 
    </AThing> 
</ArrayOfAThing> 

no veo por qué no puede hacer esto iSerializer:

<?xml version="1.0" encoding="utf-16"?> 
<ArrayOfIThing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <IThing xsi:type="IThing1"> 
    <Name>Bob</Name> 
    </IThing> 
</ArrayOfIThing> 

en lugar de lanzar una excepción.

+0

¿Has intentado compilar tu código? No creo que se compile el código anterior. Además, publique el código que usa para serializar. Hará que sea mucho más fácil ilustrar cuál es el problema. –

+0

@JohnSaunders: ver mi actualización, creo que debería estar bastante claro ahora. – Juan

+0

Para el registro, ¿cuál es la excepción completa que recibe? –

Respuesta

5

puede serializar interfaz, pero no es tan simple como clases:

http://ventspace.wordpress.com/2010/02/20/how-to-serialize-interfaces-in-net/

pero para responder a su pregunta que tengo 2 conjeturas sobre esto:

La primera razón es desde el punto de vista práctico; La semántica de serializar una interfaz es un poco borrosa. ¿Qué crees que el serializador debe serializar cuando pasas una referencia de interfaz? Si solo serializa las propiedades de interfaz que se deserializan, podría terminar con un objeto no inicializado a medio camino. No hay forma de saber qué haría con su aplicación .

Si serializas el objeto completo junto con la información de tipo, entonces serializar la interfaz realmente no te compró nada. Puede escribir la referencia como tipo de clase en primer lugar si a su aplicación realmente le importa qué objeto hay allí.

El segundo va con el propósito declarado del XmlSerializer. A pesar de el nombre engañoso Serialization XML en .NET Framework es realmente una tecnología de enlace de datos con la intención principal de mapear tipos de datos MXL definidos en esquemas XSD a tipos .NET. La definición de XSD conoce las clases abstractas de base , pero dado que está centrada en los datos, no sabe nada sobre las interfaces . Con esto en mente, hay poca motivación para admitir las interfaces en el XmlSerializer.

2

El XmlSerializer no está serializando clases abstractas. Está serializando una de varias clases de hormigón.

+2

Bueno, ¿por qué no puede hacer lo mismo con las interfaces, entonces? – Juan

+0

Las clases concretas a las que me refiero son aquellas a las que hace referencia en 'XmlInclude' –

+8

Entiendo lo que dice pero no entiendo cuál es su punto.¿Por qué no 'XmlSerializer' serializa clases concretas que implementan una interfaz del mismo modo que puede serializar clases concretas que implementan una clase abstracta, donde el objeto a ser serializado está en una lista declarada como los ejemplos que di en mi pregunta? – Juan

Cuestiones relacionadas