以前,序列化/反序列化方法使用类型Item
:
public class Item{}
现在,我有了一个名为
ItemWrapper
的新类,它是从Item
派生的,具有一个附加属性:public class ItemWrapper : Item
{
public string NewProperty { get; set; }
}
现在,我的序列化/反序列化方法使用类型
ItemWrapper
。现在我已经打破了向后兼容。我无法加载任何在旧版本中保存的Item
类型的xml文件。当反序列化方法尝试将Item
反序列化为ItemWrapper
时,我曾考虑对其进行try/catch操作,然后在catch中尝试将其反序列化为Item
。或者我可以使用xpath查看xml结构,如果没有找到ItemWrapper
,我可以假设它是Item
。这两种解决方案都让人觉得棘手,我相信有更好的方法来处理这种情况。有什么想法吗? 最佳答案
好问题。首先,虽然通过派生扩展类很好地遵守了打开/关闭原则,但如果item的所有使用者现在都使用itemwrapper,那么实现派生类就不会节省太多精力。如果itemWrapper现在是唯一正在使用的具体化,那么将其新属性与item合并并完成。
如果需要保留这两个具体化,则itemwrapper需要用几个属性来修饰,以指示xmlserializer应如何转换为xml字符串和从xml字符串转换为xml字符串。有关xml属性的信息可以找到here。
我特别提醒你注意XmlTypeAttribute。这修饰了itemwrapper类本身,并告诉xmlserializer使用特定的命名空间和类型名,而不是基于类名自动生成它们。通过声明itemwrapper类应创建并使用标记为<Item>
的xml序列化,可以使用此选项使itemwrapper与序列化item创建的xml文件兼容。但是,如果item仍然存在,则在尝试对通过序列化itemwrapper创建的文件进行反序列化时将失败,因此此解决方案不与前向兼容,因此,以前版本的软件如果没有可靠地处理序列化错误,将因没有明显的给出较新文件时的原因
因此,在序列化中实现某种版本控制方案通常是一个好主意。它可以像类型上的公共只读属性一样简单,该属性可以用xmlattribute属性标记,告诉xmlserializer将<Item>
标记构造为<Item xmlVersion="1.0.0">
。如果操作性很强,则itemwrapper可以重写该字段以返回“1.1.0”,从而使xml文件易于区分,从而允许您使用xmltextreader检查不兼容的文件版本,如果文件是由更高版本的软件生成的,则返回错误。