views:

89

answers:

2

If I have 10 different objects serialized/deserialized using a Generic T class that uses the XmlSerializer internally, how can I know which type to use when deserializing it?

MyXmlSerializer.Deserialize<MyObject> ( ... )

How can I know MyObject? All I have is a stringstream.

A: 

You can use known types:

var ttt = new []{typeof(Tst1), typeof(Tst2)};
var ser = new XmlSerializer(typeof(object), ttt);

// STEP 1
ser.Serialize(File.CreateText("D:\\test.xml"), new Tst2());

// STEP 2
var res = ser.Deserialize(File.OpenText("D:\\test.xml"));

Console.WriteLine(res);
Mike Chaliy
+2  A: 

You could implement a static method to try to deserialize each possible type. This way you wouldn't have to break your object model, to support run-time type discovery.

You would still have to have some guesses for the types stored in the XML file. The simle XML file serialization does not store detailed type information by default. It seems like there should be an attribute that forces the serializer to store the detailed type name, but I couldn't find it...

public static bool TryDeserialize<T>(XmlReader reader, out T obj) where T : class
{
    // Return null, if we can't deserialize
    obj = null;

    XmlSerializer deserializer = new XmlSerializer(typeof(T));
    bool result = deserializer.CanDeserialize(reader);

    if (result)
    {
        // Get the object, if it's possible
        obj = deserializer.Deserialize(reader) as T;
    }
    return result;
}
Scott P
You does not need attribute, just pass known types to the ctor of the XmlSerializer.
Mike Chaliy
I saw your solution. You will still need to find out what type you got, i.e. if (res.GetType() == typeof(Tst1)). I figure it's just as easy to use the type safe method above, that is similar to .Parse(..) syntax. If you don't need to know what type was deserialized, your method makes more sense.
Scott P