XmlSerializer无法处理循环引用因其设计不跟踪已序列化对象,导致重复序列化引发异常。可改用DataContractSerializer并启用PreserveObjectReferences,或重构模型、使用IXmlSerializable自定义逻辑。

XmlSerializer 在 C# 中不支持对象图中的循环引用。当两个对象相互引用(例如 A 引用 B,B 又引用 A),在序列化时会引发无限递归,最终导致 StackOverflowException 或抛出异常。
XmlSerializer 设计上是基于类型定义生成 XML 结构的,它不能跟踪已序列化的对象实例。因此,当遇到同一对象被多次引用或存在循环引用时,它无法识别“这已经是处理过的对象”,从而重复序列化,造成死循环或异常。
最直接的方式是换用支持循环引用的序列化器:
示例(DataContractSerializer):
[DataContract(IsReference = true)]
public class Person
{
[DataMember]
public string Name { get; set; }
<pre class='brush:php;toolbar:false;'>[DataMember]
public Person Spouse { get; set; }} // 序列化时启用 PreserveObjectReferences var serializer = new DataContractSerializer(typeof(Person), null, int.MaxValue, false, true, new XmlWriterSettings { Indent = true });
如果必须使用 XmlSerializer,需打破循环引用结构:
示例:
public class Parent
{
public string Name { get; set; }
public List<Child> Children { get; set; }
}
<p>public class Child
{
public string Name { get; set; }
// 不保留 Parent 引用,或标记为 [XmlIgnore]
[XmlIgnore]
public Parent Parent { get; set; }
}</p>实现 IXmlSerializable 接口,手动控制序列化过程,跳过循环部分或记录已处理的对象。
这种方式复杂度高,适用于特殊场景,一般建议优先考虑前两种方案。
基本上就这些。XmlSerializer 本身不支持循环引用,推荐改用 DataContractSerializer 并开启 IsReference 支持,或调整数据结构避免循环。简单直接,避免踩坑。
以上就是C# XmlSerializer如何处理循环引用问题的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号