7

我有以下情况。在我的 C# 应用程序中,我有一个使用 XmlSerializer 序列化的类。这个类非常复杂,我的类的一个对象作为应用程序文件保存在本地磁盘上,以后可以打开(经典的保存工作和重新打开工作)。我的问题是,在开发过程中,被序列化的对象的类可能会发生变化。我想要一个版本系统,它允许我的应用程序意识到保存的 xml 它属于旧版本但仍然可以打开。旧的应用程序版本也无法打开新的 xml 版本。

例如:

class ComplexObject
{
   public string settings1;
   public string settings2;
}

我序列化对象,在生产中发送应用程序。明天我的课变成了

class ComplexObject
{
   public string settings1;
   public string settings2;
   public string settings3;
}

我的新版本应用程序将如何打开旧类定义的序列化对象以及新类定义,在将文件加载到对象时没有错误(反序列化)

欢迎任何建议和基本样品!

谢谢

4

4 回答 4

6

这完全取决于串行器的选择。在这种情况下XmlSerializer很好,并且可以正常工作;具有新值的客户端将加载新值;没有意愿的客户。样本:

var reader = XmlReader.Create(new StringReader(
    @"<ComplexObject><foo>123</foo><bar>abc</bar></ComplexObject>"));
var ser = new XmlSerializer(typeof (ComplexObject));
var obj = (ComplexObject)ser.Deserialize(reader);

和:

public class ComplexObject
{
    public string foo;
}

可以工作和加载foo但不是bar

不要BinaryFormatter用于这个 - 这会导致一个伤害的世界。如果您想要二进制输出,请考虑类似 protobuf-net 之类的东西,它旨在公开适应版本控制。

于 2012-08-01T10:00:39.313 回答
3

版本容错序列化

简而言之,您要么将字段标记为Optional(并用默认值填充它们),要么实现反序列化构造函数,它将根据需要解析值。

于 2012-08-01T09:57:57.000 回答
2

我希望我正确理解了您的问题。您正在将一个类序列化为一个文件。然后你改变内存中的类(例如你添加另一个属性)。不,您想从文件中反序列化此类。只要您只添加新属性,这没有问题。解串器将忽略它们。他创建了您的类的一个新实例(这就是为什么可序列化类必须具有默认构造函数的原因)并尝试填充他在流中找到的属性以进行反序列化。如果您更改属性的类型或删除属性,您将无法反序列化它。

“删除属性”的一种解决方法可能是保留您有意删除的属性并进一步忽略这些属性。

您可以查看 msdn http://msdn.microsoft.com/en-us/library/ms229752%28v=vs.80%29.aspx中解释的 Version Tolerant Serialization

于 2012-08-01T09:55:57.670 回答
0

轨道 1

您可以为新版本的文件打开器创建一些if..else机制,它会尝试将文件从可能的最低版本打开到更高版本。

轨道 2

您可以将版本信息存储在文件中。

class ComplexObject
{
   public string settings1;
   public string settings2;
   public string fileVersion;
}

轨道 3

您可以为不同的文件版本使用不同的文件扩展名。(如 .doc、.docx)

于 2012-08-01T09:53:44.280 回答