仅序列化对象的已更改属性
本文关键字:属性 序列化 对象 | 更新日期: 2023-09-27 17:57:15
在C#中,是否可以仅使用修改后的值序列化对象?
例如:我将按钮对象的实例绑定到 PropertyGrid 中,并且我想仅使用更改的属性序列化该按钮对象。在 C# 中,存档的最佳方法是什么?
在您自己的类型中: 是的,你可以支持这一点 - 通过ShouldSerialize*
模式,例如:
public string Name {get;set;}
public bool ShouldSerializeName() { return Name != null; }
但是,在外部类型上 - 他们是否支持这完全取决于他们。请注意,这也会告诉属性网格要加粗哪些。
在某些情况下,[DefaultValue({the default value})]
也可以工作。
您可以通过反射迭代对象的属性,将其属性与"新鲜"实例进行比较,并以某种方式写下差异。但是,如果选择该路径,则应解决许多问题,例如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>
出乎意料的是,从你提供的信息来看。
您首先需要在对象中找到脏属性,您可以拥有另一个项目并在其他属性发生更改时对其进行跟踪。 或每个属性的 Isdirty 属性,或者是否可以与旧对象与新对象进行比较。
然后在 ToString() 方法或自定义序列化方法中,重写以仅使用更改的属性生成序列化对象自定义。
它适用于POCO对象,对于复杂的按钮对象,您必须查看如何做到这一点。
它只是和想法,如果有代码示例,则更多。