以前,序列化/反序列化方法使用类型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检查不兼容的文件版本,如果文件是由更高版本的软件生成的,则返回错误。

07-24 09:46
查看更多