How to use XmlSerializer to deserialize into an existing instance?

本秂侑毒 提交于 2019-12-08 21:00:57

问题


Is it somehow possible to use the XmlSerializer to deserialize its data into an existing instance of a class rather than into a new one?

This would be helpful in two cases:

  1. Easily merge two XML files into one object instance.
  2. Let object constructer itself be the one who is loading its data from the XML file.

If the is not possible by default it should work by using reflection (copying each property after the deserialisation) but this would be an ugly solution.


回答1:


I think you're on the right track with the Reflection idea.

Since you probably have a wrapper around the XML operations anyway, you could take in the destination object, do the deserialization normally into a new object, then do something similar to cloning by copying over one by one only the properties holding non-default values.

It shouldn't be that complex to implement this, and it would look to consumers from the rest of your application just like in-place deserialization.




回答2:


Basically, you can't. XmlSerializer is strictly constructive. The only interesting thing you can do to customize XmlSerializer is to implement IXmlSerializable and do everything yourself - not an attractive option (and it will still create new instances with the default constructor, etc).

Is xml a strict requirement? If you can use a different format, protobuf-net supports merging fragments into existing instances, as simply as:

Serializer.Merge(source, obj);



回答3:


I hit the same problem a few weeks ago.

I put a method Deserialize(string serialized form) in the ISelfSerializable interface that an entity class of mine implemented. I also made sure the interface forced the class to have a default constructor.

In my factory I created an object of that type and then deserialized the string into it.




回答4:


This is not thread safe thing to do... But you can do:

[Serializable]
public class c_Settings
{
    static c_Settings Default;
    public static SetExistingObject(c_Settings def)
    {
        Default = def;
    }

    public string Prop1;
    public bool Prop2;

    public c_Settings()
    {
        if (Default == null)
            return;
        MemberInfo[] members = FormatterServices.GetSerializableMembers(typeof(c_Settings));
        FormatterServices.PopulateObjectMembers(this, members, FormatterServices.GetObjectData(Default, members));
    }
}

This way you feed your object to deserialiser and deserialiser only overwrites whatever is written in .xml.



来源:https://stackoverflow.com/questions/531852/how-to-use-xmlserializer-to-deserialize-into-an-existing-instance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!