12

如果我想序列化一个对象,我必须使用[Serializable]属性,并且所有成员变量都将写入文件。我不知道如何进行版本控制,例如,如果我添加一个新的成员变量(重命名一个变量或只是删除一个变量)然后我打开(反序列化)文件我如何确定对象/文件版本以便我可以正确设置新成员还是进行某种迁移?如何确定变量在加载期间是否已初始化(被反序列化程序忽略)。

我知道有版本容错的方法,我可以用[OptionalField(VersionAdded = 1)]属性标记变量。如果我打开一个旧文件,框架将忽略这个可选(新变量),它只是零/空。但是我再次如何确定变量是由加载初始化还是被忽略。

我可以将类/对象版本号写入流。使用该ISerializable方法并在该constructor(SerializationInfo oInfo, StreamingContext context)方法中读取此版本号。这将准确地告诉我流中的类版本是什么。

但是我希望这种版本控制已经由 C# 中的流框架实现。我试图从中获取程序集版本,SerializationInfo但它始终设置为当前版本,而不是保存对象时使用的版本。

首选方法是什么?我在网上找到了很多文章,但我找不到解决版本控制的好方法......

任何帮助表示感谢谢谢,深渊

4

1 回答 1

2

如果我写的某些内容太明显,请原谅我,

首先,请!你必须停止认为你正在序列化一个对象......这是不正确的,因为作为你对象一部分的方法没有被持久化。您正在持久化信息 - 等等.. 仅限数据。

.NET 序列化还序列化包含程序集名称及其版本的对象的类型名称,因此当您反序列化时 - 它将持久化的程序集信息与将用信息显示的类型进行比较 - 如果它们不相同,它将返回异常。

除了版本控制问题 - 并非所有内容都可以如此轻松地序列化。尝试序列化 System.Drawing.Color 类型,您将开始理解 .NET 序列化机制过于简单的问题。

除非您打算序列化一些非常简单但没有发展计划的东西,否则我不会使用 .NET 提供的序列化机制。

让焦点回到您的问题上,您可以在此处阅读有关版本控制无知能力的信息:http: //msdn.microsoft.com/en-us/library/ms229752 (v=vs.80).aspx ,它是为 BinaryFormatter 提供的。

您还应该检查具有一些不错功能的 XML 序列化,但最大的好处是您获得了人类可读的 XML,因此即使您的类型版本控制复杂,您的数据也永远不会丢失。

但最后,我建议您要么使用带有实体框架的数据库来持久化数据,要么编写自己的平面文件管理器。虽然 EF 对大多数解决方案都非常有用,但有时你可能想要更轻的东西来持久化一些非常简单的东西。(我的意思是我再也看不到 .NET 序列化可能相关的解决方案。)

我希望这会有所帮助,祝你好运。

于 2013-03-27T00:24:31.003 回答