什么是对象图,我如何序列化一个

时间:2009-05-18 10:57:12

标签: .net serialization xml-serialization

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

3 个答案:

答案 0 :(得分:50)

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

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的期望。

答案 1 :(得分:9)

对象图是一组彼此引用的对象。

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

如果它是以XML格式进行序列化并处理对象图,则必须向每个元素添加“OBJECT_ID”(或其他一些命名的)属性。这很容易破解:如果您为要序列化的类添加了一个具有相同名称的属性会发生什么?

最简单的解决方案是不支持它。

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

答案 2 :(得分:5)

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