2012-01-13 14 views
10

Modifica Questo codice dovrebbe illustrare l'intero problema:Perché XmlSerializer può serializzare classi astratte ma non interfacce?

[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(); 
    } 
} 

Il primo text generato da aSerializer saranno:

<?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> 

non vedo il motivo per cui non si può fare questo 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> 

invece di generare un'eccezione.

+0

Hai provato a compilare il tuo codice? Non penso che il codice sopra verrà compilato. Inoltre, per favore pubblica il codice che usi per serializzare. Renderà molto più facile illustrare qual è il problema. –

+0

@JohnSaunders: Vedi il mio aggiornamento Penso che ora dovrebbe essere abbastanza chiaro. – Juan

+0

Per la cronaca, qual è l'eccezione completa che ricevi? –

risposta

5

è possibile serializzare l'interfaccia, ma non è così semplice come classi:

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

ma per rispondere alla tua domanda che ho 2 congetture su questo:

La prima ragione è dal lato pratico; La semantica della serializzazione di un'interfaccia è un po 'sfocata. Cosa pensi che il serializzatore dovrebbe serializzare quando si passa in un riferimento all'interfaccia? Se solo serializzi le proprietà dell'interfaccia, la deserializzazione potrebbe quindi terminare con un oggetto non inizializzato a metà strada. Non si può dire cosa potrebbe fare a l'applicazione.

Se serializzi l'oggetto completo insieme alle informazioni sul tipo, allora la serializzazione dell'interfaccia non ti ha davvero comprato nulla. Potresti digitare il riferimento come tipo di classe in primo luogo se la tua applicazione in realtà si preoccupa di quale oggetto ci sia.

Il secondo va allo scopo dichiarato di XmlSerializer. Nonostante il nome ingannevole Serializzazione XML in .NET Framework è in realtà una tecnologia di collegamento dati con l'intenzione primaria di mappare i tipi di dati MXL definiti in schemi XSD in tipi .NET. La definizione XSD conosce le classi astratte di base , ma dal momento che è incentrata sui dati, non sa nulla delle interfacce . Con questo in mente c'è poca motivazione a supportare le interfacce in XmlSerializer.

2

XmlSerializer non sta serializzando le classi astratte. Si sta serializzando una delle diverse classi di calcestruzzo.

+2

Bene, perché allora non può fare lo stesso con le interfacce? – Juan

+0

Le classi concrete a cui mi riferisco sono quelle a cui si fa riferimento in 'XmlInclude' –

+8

Capisco cosa stai dicendo ma non capisco quale sia il tuo punto.Perché 'XmlSerializer' non può serializzare classi concrete che implementano un'interfaccia proprio come può serializzare classi concrete che implementano una classe astratta, in cui l'oggetto da serializzare si trova in una lista dichiarata come gli esempi che ho dato nella mia domanda? – Juan

Problemi correlati