问题描述
如果我想序列化一个对象,我必须使用 [Serializable]
属性,并且所有成员变量都将写入文件.我不知道如何进行版本控制,例如如果我添加一个新成员变量(重命名一个变量或只是删除一个变量)然后我打开(反序列化)文件我如何确定对象/文件版本以便我可以正确设置新成员或进行某种迁移?如何确定变量在加载期间是否已初始化(被反序列化程序忽略).
If I want to serialize an object I have to use [Serializable]
attribute and all member variables will be written to the file. What I don't know how to do versioning e.g. if I add a new member variable (rename a variable or just remove a variable) and then I open (deserialize) the file how can I determine the object/file version so I can correctly set the new member or take some kind of migration? How can I determine that the variable was initialized during the load or not (ignored by deserializer).
我知道有版本容忍的方法,我可以用 [OptionalField(VersionAdded = 1)]
属性标记变量.如果我打开一个旧文件,框架将忽略这个可选(新变量),它只是零/空.但是我又如何确定变量是由加载初始化还是被忽略.
I know that there are version tolerant approaches and I can mark variables with [OptionalField(VersionAdded = 1)]
attribute. If I open an old file the framework will ignore this optional (new variable) and it will be just zero/null. But again how can I determine if the variable is initialized by load or it was ignored.
我可以将类/对象版本号写入流.使用 ISerializable
方法并在 constructor(SerializationInfo oInfo, StreamingContext context)
方法中读取此版本号.这将准确地告诉我流中的类版本是什么.
I can write the class/object version number to the stream. Use the ISerializable
approach and in the constructor(SerializationInfo oInfo, StreamingContext context)
method read this version number. This will exactly tell me what is the class version in the stream.
但是我希望这种版本控制已经由 C# 中的流框架实现.我试图从 SerializationInfo
获取程序集版本,但它始终设置为当前版本,而不是保存对象时使用的版本.
However I expected that such kind of versioning is already implemented by the streaming framework in C#. I tried to obtain the Assembly version from the SerializationInfo
but it is always set to current version not to the version which was used when the object was saved.
首选方法是什么?我在网上找到了很多文章,但我找不到解决版本控制的好方法......
What is the preferred approach? I found a lot of articles on the net, but I could not find a good solution for this which addresses versioning...
任何帮助表示赞赏谢谢,深渊
Any help is appreciated Thanks, Abyss
推荐答案
如果我写的有些太明显,请见谅,
Forgive me if some of what I write is too obvious,
首先,拜托!你必须停止认为你正在序列化一个对象......这是不正确的,因为作为对象一部分的方法没有被持久化.您正在持久化信息 - 所以......仅限数据.
First of all, please! you must stop thinking that you are serializing an object... That is simply incorrect as the methods which are part of your object are not being persisted. You are persisting information - and so.. DATA only.
.NET 序列化还序列化包含程序集名称及其版本的对象的类型名称,因此当您反序列化时 - 它会将持久化的程序集信息与将通过信息显示的类型进行比较 - 如果它们不是同样会返回异常.
.NET serialization also serializing the type name of your object which contain the assembly name and its version, so when you deserialize - it compares the persisted assembly information with the type that will be manifested with the information - if they are not the same it will return an exception.
除了版本控制问题 - 并非所有内容都可以如此轻松地序列化.尝试序列化 System.Drawing.Color 类型,您将开始了解 .NET 序列化机制过于简单的问题.
Beside the versioning problem - not everything can be serialized so easily.. try to serialize a System.Drawing.Color type and you will begin to understand the problems with the over simplistic mechanism of .NET serialization.
除非您打算序列化一些非常简单且没有发展计划的东西,否则我不会使用 .NET 提供的序列化机制.
Unless you plan to serialize something really simple which has no plans to evolve I wouldn't use the serialization mechanism provided by .NET.
让焦点回到您的问题上,您可以在此处阅读有关版本控制无知能力的信息:http://msdn.microsoft.com/en-us/library/ms229752(v=vs.80).aspx 是为 BinaryFormatter 提供的.
Getting the focus back to your question, you can read here about the versioning ignorance ability: http://msdn.microsoft.com/en-us/library/ms229752(v=vs.80).aspx which is provided for BinaryFormatter.
您还应该检查具有一些不错功能的 XML 序列化,但最大的好处是您获得了人类可读的 XML,因此即使您的类型版本控制复杂,您的数据也永远不会丢失.
You should also check XML Serialization which has some nice abilities, but the biggest benefit is that you getting an XML which is Human readable so your data will never be lost even if you had complication with the versioning of your types.
但最后,我建议您使用带有实体框架的数据库来持久化您的数据或编写自己的平面文件管理器.虽然 EF 对大多数解决方案都非常有用,但有时您可能需要更轻的东西来持久化非常简单的东西.(我的意思是我再也看不到与 .NET 序列化相关的解决方案了.)
But finally, I recommend you either use Database with Entity Framework to persist your data or write your own flat file manager.. while EF is very good for most solutions, sometime you might want something lighter to persist something very simple. (my imply is that I can no longer see a solution where .NET serialization can be relevant.)
我希望这会有所帮助,祝你好运.
I hope this helps, Good luck.
这篇关于C# 中的序列化和对象版本控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!