如果您有一个引用其他对象(例如实例 B 和 C)的对象实例 A,并且您将 A 二进制序列化到文件中,会发生什么?您现在是否拥有包含 A、B 和 C 的序列化数据?
它是如何工作的?如果我反序列化数据会得到什么?A、B、C??
(也可以随意添加内部工作解释)。
如果您有一个引用其他对象(例如实例 B 和 C)的对象实例 A,并且您将 A 二进制序列化到文件中,会发生什么?您现在是否拥有包含 A、B 和 C 的序列化数据?
它是如何工作的?如果我反序列化数据会得到什么?A、B、C??
(也可以随意添加内部工作解释)。
所有对其他对象的引用也将被序列化。如果您对数据进行反序列化,您最终将得到一个完整的工作数据集,包括对象 A、B 和 C。这可能是二进制序列化的主要好处,而不是 XML 序列化。
如果你的对象引用的任何其他类没有用[Serializable]
属性标记,你会SerializationException
在运行时得到一个这在当前版本的 VS 中不再存在):
除此之外,我不确定您希望了解哪些“内部事物”。序列化使用反射遍历对象的公共和私有字段,将它们转换为字节流,最终写入数据流。在反序列化期间,会发生相反的情况:从数据流中读取字节流,用于合成对象的精确复制以及类型信息。对象中的所有字段都具有与之前相同的值;反序列化对象时不调用构造函数。考虑它的最简单方法是,您只是在原地拍摄对象的快照,您可以随意恢复到其原始状态。
负责实际序列化和反序列化的类称为格式化程序(它总是从IFormatter
接口继承)。它的工作是生成一个“对象图”,它是一个广义树,其中包含正在序列化/反序列化的对象作为其根。如上所述,格式化程序使用反射遍历此对象图,序列化/反序列化该对象包含的所有对象引用。格式化程序也足够智能,知道不会多次序列化图中的任何对象。如果两个对象引用实际上指向同一个对象,则会检测到该对象,并且该对象只会被序列化一次。这种逻辑和其他逻辑可防止进入无限循环。
当然,很容易对这个过程的工作原理有一个很好的总体了解。实际编写自己实现它的代码要困难得多。幸运的是,这已经为您完成了。.NET Framework 的部分要点是所有这些复杂的序列化逻辑都内置,让您不必担心。我并没有声称自己了解所有这些,您当然也不需要充分利用它提供的功能。多年来手工编写所有这些代码终于结束了。你应该高兴,而不是担心实现细节。:-)
首先,对象 A 的类型必须用 [Serializable] 属性标记。序列化 A 将序列化其所有成员数据,无论是私有的还是公共的,只要成员的类型也用 [Serializable] 标记(或者使用您的示例,前提是 B 和 C 的类型标记为 [Serializable])。尝试直接或间接序列化非 [Serializable] 类型的数据将导致异常。
许多内置的 .NET 类型已经被标记为 [Serializable],包括 System.Int32 (int)、System.Boolean (bool) 等。
您可以在此处阅读有关 .NET 序列化的更多信息:http: //msdn.microsoft.com/en-us/library/4abbf6k0.aspx。
主对象引用的对象也必须是 [Serializable]。提供所有这些都是由格式化程序自动完成的。