views:

543

answers:

3

Say I have a couple of basic objects like so:

[Serializable]
public class Base
{

    public string Property1 { get; set; }
    public int Property2 { get; set; }
}

[Serializable]
public class Sub: Base
{
    public List<string> Property3 { get; set; }

    public Sub():base()
    {
        Property3 = new List<string>();
    }        
}

And I serialize them like so:

Sub s = new Sub {Property1 = "subtest", Property2 = 1000};
s.Property3.Add("item 1");
s.Property3.Add("item 2");

XmlSerializer sFormater = new XmlSerializer(typeof(Sub));
using (FileStream fStream = new FileStream("SubData.xml", 
    FileMode.Create, FileAccess.Write, FileShare.None))
{
    sFormater.Serialize(fStream, s);
}

How can I deserialize them, so that I get back the correct class?

As in, I'd want something like this

XmlSerializer bFormater = new XmlSerializer(typeof (Base));
Base newBase;
using (FileStream fStream = new FileStream("BaseData.xml", 
    FileMode.Open, FileAccess.Read, FileShare.Read))
{
    newBase = (Base) bFormater.Deserialize(fStream);
}

Except I'd be able to pass it an XML file for any class that descends from Base and the correct class would be created.

I'm thinking I could read the name of the root node of the XML and use a switch statement to create the correct XmlSerializer, but I was wondering if there was a simpler way.

+4  A: 

You can read the XML file's root node and instead of using a switch statement, you can write your code like this -

Type yourType = Type.GetType("Your Type");
XmlSerializer xs = new XmlSerializer(yourType);

I don't think there's any way other than reading the XML because if you don't know the type, you can't do anything.

Kirtan
A: 

As far as I know, there is no simplier way to do this.

I personally prefer a more generic solution (as I have to serialize a lot of various classes in my code): to keep type name serialized together with the value.

You can take a look at this question for some details: http://stackoverflow.com/questions/824162/serialise-to-xml-and-include-the-type-of-the-serialised-object

Yacoder
+2  A: 

Use the [XmlInclude] attribute on your base class to tell the XML serializer about derived classes, so it can figure out what to create. Your last code snippet should then work correctly.

Anton Tykhyy
That works great. Thanks.
Ray
One addition thing, when I serialized the sub class, I need to do it with an XmlSerializer created on the Base class (not the Sub class).
Ray