我最近一直在阅读有关序列化的内容。我已经读过,当我使用XmlSerialization时,我无法序列化对象图。什么是对象图以及为什么我不能简单地序列化它?
答案 0 :(得分:50)
对象图不是单个对象,而是一组相关对象。举个简单的例子,考虑一下:
public class Node {
public string Name {...}
public Node Parent {...}
public List<Node> Children {...}
}
每个孩子都知道父母(父母知道孩子)。
问题是xml是一个基于对象属性的树......它想要只是走它们 - 即使用简单的父/子:
将序列化为:
<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)序列化过程需要跟踪每个对象的身份,并使用某种形式的标记和扫描算法来确保对象不被(反)序列化两次。