如何使用XmlSerializer反序列化为现有实例?

时间:2009-02-10 11:04:03

标签: c# .net serialization .net-2.0

是否有可能使用XmlSerializer将其数据反序列化为现有的类实例而不是新的实例?

这在两种情况下会有所帮助:

  1. 轻松将两个XML文件合并到一个对象实例中。
  2. 让object constructer本身就是从XML文件加载数据的人。
  3. 如果默认情况下不可能,它应该使用反射(在反序列化后复制每个属性),但这将是一个丑陋的解决方案。

4 个答案:

答案 0 :(得分:4)

基本上,你不能。 XmlSerializer具有严格的建设性。您可以自定义XmlSerializer的唯一有趣的事情是实现IXmlSerializable并自己完成所有事情 - 这不是一个有吸引力的选项(它仍将使用默认构造函数创建新实例等)。

xml严格要求吗?如果您可以使用其他格式,protobuf-net支持将片段合并到现有实例中,就像:

Serializer.Merge(source, obj);

答案 1 :(得分:1)

我认为你的反思理念是正确的。

由于你可能还有一个XML操作的包装器,你可以接收目标对象,通常将反序列化作为一个新对象,然后通过逐个复制只保存非属性的属性来做类似于克隆的操作。默认值。

实现这一点应该不是那么复杂,并且它会从应用程序的其余部分看待消费者,就像就地反序列化一样。

答案 2 :(得分:0)

几周前我遇到了同样的问题。

我在ISelfSerializable接口中放置了一个方法Deserialize(字符串序列化表单),该接口是我实现的实体类。我还确保接口强制类具有默认构造函数。

在我的工厂里,我创建了一个这种类型的对象,然后将字符串反序列化为它。

答案 3 :(得分:0)

这不是线程安全的事情......但你可以这样做:

[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));
    }
}

通过这种方式,您可以将对象反馈给反序列化器,而反序列化器只会覆盖以.xml编写的任何内容。