什么是对象图以及如何序列化一个对象图
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 由一组相互持有引用的对象组成。如果您有一个没有反向链接的对象树,则序列化和反序列化很简单。对于一般图,(反)序列化过程需要跟踪每个对象的身份,并使用某种形式的标记和扫描算法来确保对象不会被(反)序列化两次。
【讨论】:
以上是关于什么是对象图以及如何序列化一个对象图的主要内容,如果未能解决你的问题,请参考以下文章