.NET Binary Serialize对象,引用其他对象。 。 。怎么了?

时间:2011-02-05 07:57:44

标签: .net binary-serialization object-reference object-graph

如果你有一个引用其他对象的对象实例A(例如实例B和C),并且二进制序列化A到文件,会发生什么?您现在有包含A,B和C的序列化数据吗?

它是如何工作的?如果我反序列化数据,我会得到什么? A,B和C ??

(请随意提供内部工作原理解释)。

3 个答案:

答案 0 :(得分:7)

所有对其他对象的引用也将被序列化。如果对数据进行反序列化,最终将得到一组完整的,有效的数据集,包括对象A,B和C.这可能是二进制序列化的主要好处,而不是XML序列化。

如果您的对象持有引用的任何其他类未标记为[Serializable] attribute,则您将在运行时获得SerializationException(其图像被无耻地从web;在当前版本的VS中,运行时错误甚至看起来都不再像这样:

Example of an unhandled SerializationException

除此之外,我不太确定你希望了解的“内部事物”。序列化使用reflection遍历对象的公共和私有字段,将它们转换为字节流,最终写入数据流。在反序列化期间,反向发生:从数据流中读入字节流,用于合成对象的精确复制以及类型信息。对象中的所有字段都具有与之前相同的值;在反序列化对象时,构造函数是 not 。考虑它的最简单方法是,您只需要对象的就地快照,即可随意恢复到原始状态。

负责实际序列化和反序列化的类称为格式化程序(它始终继承自IFormatter interface)。它的工作是生成一个“对象图”,它是一个通用树,包含作为其根被序列化/反序列化的对象。如上所述,格式化程序使用反射来遍历此对象图,序列化/反序列化该对象包含的所有对象引用。格式化程序也足够智能,知道不会多次序列化图形中的任何对象。如果两个对象引用实际上指向同一个对象,则会检测到该对象,并且该对象仅被序列化一次。这个和其他逻辑阻止进入无限循环。

当然,很容易对这个过程的工作原理有一个很好的了解。实际编写实现它的代码实际上更难 。幸运的是,这已经为你完成了。 .NET Framework的部分重点是内置所有这些复杂的序列化逻辑,让您免于担心。我并不声称自己理解所有这些,你当然也不需要充分利用它提供的功能。多年来手工编写所有代码终于结束了。你应该欢欣鼓舞,而不是担心实施细节。 : - )

答案 1 :(得分:4)

首先,必须使用[Serializable]属性标记对象A的类型。序列化A将序列化其所有成员数据,私有或公共,只要成员的类型也标记为[Serializable](或使用您的示例,前提是B和C的类型标记为[Serializable])。尝试直接或间接地序列化不是[Serializable]类型的数据将导致异常。

许多内置的.NET类型已标记为[Serializable],包括System.Int32(int),System.Boolean(bool)等。

您可以在此处阅读有关.NET序列化的更多信息:http://msdn.microsoft.com/en-us/library/4abbf6k0.aspx

答案 2 :(得分:1)

主对象引用的对象也必须是[Serializable]。提供所有这些都由格式化程序自动完成。