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

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

【问题讨论】:

    标签: .net serialization xml-serialization


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

      【讨论】:

        猜你喜欢
        • 2010-10-01
        • 2017-08-15
        • 2010-11-21
        • 2010-10-21
        • 2021-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多