Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to serialize a derived class as its base class

I have a derived class that adds only methods to a base class. How can one serialize the derived class so that it matches the serialization of the base class? i.e. The serialized xml of the derived class should look like:

<BaseClass>
  ...
</BaseClass>

e.g. The following will throw an InvalidOperationException

The type DerivedClass was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.

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);
like image 328
Chris Herring Avatar asked Dec 01 '09 05:12

Chris Herring


2 Answers

You'll have to pass GetType(DerivedClass) to the serializer constructor, it must match the type of the object you serialize. You can use the <XmlRoot> attribute to rename to the root element. This example code worked as intended:

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 { }
like image 140
Hans Passant Avatar answered Sep 27 '22 16:09

Hans Passant


You can also implement ICloneable interface for BaseClass and then do :

var sw = new StringWriter()

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

Console.WriteLine(sw.ToString())

Not a perfect approche, but if your base class is simple then it should also work.

like image 22
Mariusz Gorzoch Avatar answered Sep 27 '22 16:09

Mariusz Gorzoch