简体   繁体   English

C#序列化对象版本

[英]C# serialized object versions

I have the following situation. 我有以下情况。 In my C# application, I have a class which i serialize using XmlSerializer. 在我的C#应用​​程序中,我有一个使用XmlSerializer序列化的类。 The class is pretty complex, and an object of my class gets saved on local disc as an application file, which can be opened later (classic save work and reopen work). 该类非常复杂,我的类的一个对象作为一个应用程序文件保存在本地光盘上,可以在以后打开(经典的保存工作和重新打开工作)。 My problems is that during the development, the class of the object which gets serialized might change. 我的问题是在开发过程中,被序列化的对象的类可能会改变。 I would like to have a version system, which allows my app to realize that the saved xml it belongs to an older version but still can be opened. 我想有一个版本系统,它允许我的应用程序意识到它保存的xml属于旧版本,但仍然可以打开。 Old app versions can not open new xml versions as well. 旧的app版本也无法打开新的xml版本。

For example: 例如:

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

I serialize object, send app in production. 我序列化对象,在生产中发送应用程序。 Tomorrow my class became 明天我的班级成了

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

How will my new version of app open serialized objects of old class definitions as well as new class definition with no error on loading file to object (deserialization) 我的新版本的应用程序将如何打开旧类定义的序列化对象以及新的类定义,并且在将文件加载到对象时没有错误(反序列化)

Any suggestions and basic samples are welcomed! 欢迎任何建议和基本样品!

Thanks 谢谢

It all depends on the choice of serializer. 这一切都取决于串行器的选择。 In the case of XmlSerializer this is fine and will just work; XmlSerializer的情况下,这很好,只会工作; clients with the new value will load the new value; 具有新值的客户端将加载新值; clients without will not. 没有的客户不会。 Sample: 样品:

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);

with: 有:

public class ComplexObject
{
    public string foo;
}

which works and loads foo but not bar . 它工作和加载foo但不是bar

Do not use BinaryFormatter for this - that leads to a world of hurt. 不要使用BinaryFormatter - 这会导致一个受伤的世界。 If you want binary output, consider something like protobuf-net which is designed to be overtly accommodating with versioning. 如果你想要二进制输出,可以考虑像protobuf-net这样的东西,它可以完全适应版本控制。

Version-tolerant serialization 版本容忍的序列化

In short, you either mark fields as Optional (and fill them with default values) or implement deserialization constructor which will parse values as you want them. 简而言之,您可以将字段标记为Optional (并使用默认值填充它们)或实现反序列化构造函数,该构造函数将根据需要解析值。

I hope I understood your problem correctly. 我希望我能正确理解你的问题。 You're having a class serialized to a file. 您正在将类序列化为文件。 Then you change the class in memory (eg you add another property). 然后在内存中更改类(例如,添加另一个属性)。 No you want to deserialize this class from the file. 不,您想要从文件反序列化此类。 This is no problem as long as you only add new properties. 只要您只添加新属性,这就没问题了。 They will be ignored by the deserializer. 它们将被解串器忽略。 He creates a new instance of your class (that is the reason, why serializable classes have to have a default constructor) and tries to fill the properties he finds in the stream to derserialize. 他创建了一个类的新实例(这就是为什么可序列化的类必须有一个默认的构造函数)并尝试将他在流中找到的属性填充到derserialize。 If you change property's type or remove a property, you won't be able to deserialize that. 如果更改属性的类型或删除属性,则无法对其进行反序列化。

One workaround for "remove properties" maybe to keep properties you intentionally wanted to remove and ignore those furthermore. “删除属性”的一种解决方法可能是保留您有意删除的属性,并进一步忽略这些属性。

You can take a look at Version Tolerant Serialization explained in msdn http://msdn.microsoft.com/en-us/library/ms229752%28v=vs.80%29.aspx 您可以在msdn http://msdn.microsoft.com/en-us/library/ms229752%28v=vs.80%29.aspx中查看版本容忍序列化。

Track 1 轨道1

You could create some if..else mechanism for a new version file opener which would try to open file from lowest possible version to higher. 您可以为新版本文件打开器创建一些if..else机制,该机制会尝试从最低版本打开文件到更高版本。

Track 2 轨道2

You could store version information in your files. 您可以在文件中存储版本信息。

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

Track 3 轨道3

You could use different file extensions for different file versions.(like .doc, .docx) 您可以为不同的文件版本使用不同的文件扩展名。(例如.doc,.docx)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM