什么是对象图以及如何序列化一个对象图

Posted

技术标签:

【中文标题】什么是对象图以及如何序列化一个对象图【英文标题】:What is an object graph and how do I serialize one 【发布时间】:2010-10-27 00:05:09 【问题描述】:

我最近一直在阅读有关序列化的内容。我读过,当我使用 XmlSerialization 时,我无法序列化对象图。什么是对象图,为什么我不能简单地序列化它?

【问题讨论】:

【参考方案1】:

对象图不是单个对象,而是一组相关对象。举个简单的例子,考虑:

public class Node 
    public string Name ...
    public Node Parent ...
    public List<Node> Children ...

每个孩子都知道父母(父母也知道孩子)。

问题在于 xml 是一个基于对象属性的树......它只想遍历它们 - 即使用简单的父/子:

A(知道 B 是它的孩子) B(知道 A 是它的父级)

将序列化为:

<Node>
  <Name>A</Name>
  <!-- no Parent as A is the top node, so null -->
  <Children>
     <Node>
        <Name>B</Name>
        <Parent>
           <Node>
              <Name>A</Name>
              *** boom ***

您可以看到我们回到了 A,所以我们现在处于无限循环中。

XmlSerializer 可以序列化数据的,但不能序列化完整的图。您可以标记要忽略的属性,例如:

[XmlIgnore]
public Node Parent ...

现在它可以工作了,但之后我们必须修复Parent

相比之下,其他一些序列化程序可以处理图形(DataContractSerializer 可以按需处理)。它通过针对唯一键跟踪对象来做到这一点 - 但是输出不是您对常规 xml 的期望。

【讨论】:

【参考方案2】:

对象图是一组相互引用的对象。

序列化对象图很棘手。序列化程序必须为每个对象分配一个唯一 ID,然后用唯一 ID 替换引用。

如果它以 XML 格式序列化并处理对象图,则必须为每个元素添加一个“OBJECT_ID”(或其他命名的)属性。这很容易被打破:如果你在你正在序列化的类中添加一个同名的属性会发生什么?

最简单的解决办法就是不支持。

.NET 提供二进制序列化来处理这个问题以及循环引用的问题。

【讨论】:

我不明白你说的很容易破解是什么意思。如果我在类中添加一个属性会发生什么坏事?【参考方案3】:

一般对象graph 由一组相互持有引用的对象组成。如果您有一个没有反向链接的对象树,则序列化和反序列化很简单。对于一般图,(反)序列化过程需要跟踪每个对象的身份,并使用某种形式的标记和扫描算法来确保对象不会被(反)序列化两次。

【讨论】:

以上是关于什么是对象图以及如何序列化一个对象图的主要内容,如果未能解决你的问题,请参考以下文章

面向对象中经常会用到序列图讲解

运行时序列化

UML之序列图

防止对象图序列化的循环引用

UML - EA 序列图

JAVA怎么把数据流转换成对象