仅序列化对象的更改属性

Serialize only changed properties of the object

在 C# 中是否可以仅使用修改后的值序列化对象?

例如:我将 Button 对象的实例绑定到 PropertyGrid 中,我想用仅更改的属性序列化该 Button 对象。在 C# 中,最好的存档方法是什么?

从你提供的信息来看,出乎意料。

您首先需要找到对象中的脏属性,您可以有另一个项目并在其他属性发生变化时跟踪它。或每个属性 isdirty 属性,或者如果您可以将旧对象与新对象进行比较。

然后在 ToString() 方法或您自定义的序列化方法中,重写以仅使用更改的属性生成自定义的序列化对象。

它适用于POCO对象,对于你制作的复杂按钮对象,你必须看看如何去做。

它的公正和想法,如果有代码示例会更多。

您可以通过反射迭代对象的属性,将其属性与 'fresh' 实例进行比较,并以某种方式记下差异。但是,如果您选择该路径,您应该解决许多问题,例如 null 处理、序列化不可序列化类型、序列化引用等。这里只是一个草图:

    public static string ChangedPropertiesToXml<T>(T changedObj)
    {
        XmlDocument doc=new XmlDocument();
        XmlNode typeNode = doc.CreateNode(XmlNodeType.Element, typeof (T).Name, "");
        doc.AppendChild(typeNode);
        T templateObj = Activator.CreateInstance<T>();
        foreach (PropertyInfo info in
            typeof (T).GetProperties(BindingFlags.Instance | BindingFlags.Public))
        {
            if (info.CanRead && info.CanWrite)
            {
                object templateValue = info.GetValue(templateObj, null);
                object changedValue = info.GetValue(changedObj, null);
                if (templateValue != null && changedValue != null && !templateValue.Equals(changedValue))
                {
                    XmlElement elem =  doc.CreateElement(info.Name);
                    elem.InnerText = changedValue.ToString();
                    typeNode.AppendChild(elem);
                }
            }
        }
        StringWriter sw=new StringWriter();
        doc.WriteContentTo(new XmlTextWriter(sw));
        return sw.ToString();
    }

来电:

Button b = new Button();
b.Name = "ChangedName";
Console.WriteLine(SaveChangedProperties(b));

一次输出:

<Button>
   <Name>ChangedName</Name>
</Button>

在你自己的类型中:是的,你可以支持这个 - 通过 ShouldSerialize* 模式,例如:

public string Name {get;set;}
public bool ShouldSerializeName() { return Name != null; }

然而,在 外部 类型上——是否支持这个完全取决于他们。请注意,这也会告诉 属性-grid 哪个要加粗。

在某些情况下,[DefaultValue({the default value})] 也可以。