无法对派生类进行deserilize。但如果它在列表或字典中,它就可以工作。有什么想法吗?

时间:2017-08-01 16:31:38

标签: c# serialization datacontract

我遇到了一个奇怪的问题,如果我把它放在一个List中,我可以序列化一个派生类,但是当它放在它自己的时候却没有。

我正在使用这些方法来序列化和反序列化(找到它们here):

    public static string Serialize(T obj)
    {
        using (MemoryStream memoryStream = new MemoryStream())
        using (StreamReader reader = new StreamReader(memoryStream))
        {
            DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
            serializer.WriteObject(memoryStream, obj);
            memoryStream.Position = 0;
            return reader.ReadToEnd();
        }
    }

    public static T Deserialize(string xml, Type toType)
    {
        using (Stream stream = new MemoryStream())
        {
            byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);
            stream.Write(data, 0, data.Length);
            stream.Position = 0;
            DataContractSerializer deserializer = new DataContractSerializer(toType);
            return (T)deserializer.ReadObject(stream);
        }
    }

我有一个基类Entity。派生类Thing

[DataContract]
[KnownType(typeof(Thing))]
Class Entity
{
}

[DataContract]
Class Thing : Entity
{
}

现在,当我尝试序列化实例化为Thing的对象时,没有问题,但反序列化会产生错误。

            Thing e = new Thing();
            string xmlstring = XML<Entity>.Serialize(e); 

            Entity testE = XML<Entity>.Deserialize(xmlstring, typeof(Entity));

错误说明Expected element Entity from ... . Element Thing was found.(不是用英文写的)。

但奇怪的是,如果我将对象放入列表并对列表进行序列化 - 反序列化,它就可以工作。

            Thing e = new Thing();
            List<Entity> test = new List<Entity>();
            test.Add(e);

            var xmlstring = XML<List<Entity>>.Serialize(test);

            List<Entity> test2 = XML<List<Entity>>.Deserialize(xmlstring, typeof(List<Entity>));

现在test2的条目包含正确的Thing项。即使这可能是一种解决方法,它肯定必须是一种更简单的方法,它必须是一个很容易修复的东西我想?有什么想法吗?我错过了什么?

(当然,当我将Thing对象反序列化为Thing - 对象时它会起作用,但这不是我想要的,反序列化时我不会事先知道该类。)

1 个答案:

答案 0 :(得分:0)

似乎在考虑@Jaya's评论之后我自己找到了解决方法。我修改了serialize方法以强制它序列化为基类类型。最初我认为这不会起作用,但确实如此!

public static string Serialize(T obj, Type toType)
{
    using (MemoryStream memoryStream = new MemoryStream())
    using (StreamReader reader = new StreamReader(memoryStream))
    {
        DataContractSerializer serializer = new DataContractSerializer(toType);
        serializer.WriteObject(memoryStream, obj);
        memoryStream.Position = 0;
        return reader.ReadToEnd();
    }
}