2009-12-01 7 views
6

J'ai une classe dérivée qui ajoute seulement des méthodes à une classe de base. Comment sérialiser la classe dérivée afin qu'elle corresponde à la sérialisation de la classe de base? à savoir le xml sérialisée de la classe dérivée devrait ressembler à:Comment sérialiser une classe dérivée comme classe de base

<BaseClass> 
    ... 
</BaseClass> 

par exemple Ce qui suit va lancer une exception InvalidOperationException "Le type DerivedClass n'était pas prévu.Utilisez l'attribut XmlInclude ou SoapInclude pour spécifier les types qui ne sont pas connus statiquement."

Class BaseClass {} 

Class DerivedClass : BaseClass {} 

DerivedClass derived = new DerivedClass(); 

StreamWriter stream = new StreamWriter("output file path"); 
XmlSerializer serializer = new XmlSerializer(GetType(BaseClass)); 
serializer(stream, derived); 

Répondre

4

Vous devrez passer GetType (DerivedClass) au constructeur du sérialiseur, il doit correspondre au type de l'objet que vous sérialisez. Vous pouvez utiliser l'attribut <XmlRoot> pour renommer l'élément racine. Ce code d'exemple a fonctionné comme prévu:

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

class Program { 
    static void Main(string[] args) { 
    var obj = new DerivedClass(); 
    obj.Prop = 42; 
    var xs = new XmlSerializer(typeof(DerivedClass)); 
    var sw = new StringWriter(); 
    xs.Serialize(sw, obj); 
    Console.WriteLine(sw.ToString()); 

    var sr = new StringReader(sw.ToString()); 
    var obj2 = (BaseClass)xs.Deserialize(sr); 
    Console.ReadLine(); 
    } 
} 

public class BaseClass { 
    public int Prop { get; set; } 
} 
[XmlRoot("BaseClass")] 
public class DerivedClass : BaseClass { } 
+0

fait le travail, merci. –

+0

Les gars, j'ai le même problème ici, mais cela n'a pas fonctionné. Ma classe de base a été créée à partir d'un XSD, donc je ne sais pas quoi mettre dans le [XmlRoot] est le nom de la classe, ou le nom de l'élément racine de la classe de base (devrais-je spécifier son espace de noms, etc etc?) – Tejo

+1

Existe-t-il une solution si seulement la base mais pas le type dérivé est connu? –

0

Je ne l'ai pas essayé mais ne pouvez-vous pas simplement le lancer?

serializer(stream, (BaseClass)derived); 

Modifier

En outre, si vous voulez avoir un seul XmlSerialiser qui peut faire face à plusieurs classes dérivées & la classe de base, vous devez spécifier tous les types dans le constructeur de XmlSerialiser.

XmlSerializer serializer = new XmlSerializer(typeof(BaseClass), new Type[] {typeof(DerivedClass)}); 

Ensuite, il sera heureux de sérialiser plusieurs types. Cependant, vous devrez également utiliser la solution mentionnée ci-dessus pour que le fichier XML de sortie corresponde aux classes.

+1

Pas la même InvalidOperationException est levée –

0

Après un peu de googler;) je peux dire que vous aurez besoin d'un peu plus de code et mettre en œuvre IXmlSerializable pour votre classe de base, déclarant toutes les méthodes d'interface comme virtuelle et les remplaçant sur votre classe dérivée. Voici un exemple topic et similar problem résolus par l'interface mentionnée.

1

Vous pouvez également implémenter l'interface ICloneable pour BaseClass puis faire:

var sw = new StringWriter() 

var base = (derived as BaseClass).Clone() 
var serializer = new XmlSerializer(typeof(BaseClass)) 
serializer.Serialize(sw, base) 

Console.WriteLine(sw.ToString()) 

Pas parfait approach, mais si votre classe de base est simple, alors il devrait également fonctionner.

Questions connexes