序列化中的循环引用问题

初次接触序列化,就遇上了一个神奇的bug,思考了很久又逛了论坛,最终算是自己给了自己一个比较清晰的解释。

 

在网上查到的循环引用问题,主要是针对这种情况,场景设计以及分析来源于一下几个网址,侵删:

http://www.blogjava.net/sway/archive/2009/01/05/249867.html

https://www.cnblogs.com/zhxshseu/p/5285375.html

https://www.cnblogs.com/slyfox/p/7388743.html

https://blog.csdn.net/ZslLoveMiwa/article/details/80813568

这里先举一个循环引用的实例:

namespace 序列化循环引用
{
    public class Parent
    {
        public string Name { get; set; }
        public string Age { get; set; }
        public string Gender { get; set; }
        public Child Child { get; set; }
    }
     
    public class Child
    {
        public string Name { get; set; }
        public Parent Parent { get; set; }
    }

}
private void Form1_Load(object sender, EventArgs e)
{
    Child child = new Child();
    Parent person = new Parent() { Name = "鲁迅认识的那只猹", Age = "18", Gender = "男", Child = child };
    child.Name = "Test";
    child.Parent = person;

    JavaScriptSerializer jss = new JavaScriptSerializer();
    string value = jss.Serialize(jss);
    Console.WriteLine(value);
}

这个时候编译器就会报错:A circular reference was detected while serializing an object of type .........

这里就是循环引用在序列化时会产生的异常,因为假设A类对象中有B类对象而B类对象中有A类对象,那么在序列化A类对象的时候,会从A查到B,而查B类的内容时有找到A,因此陷入了一个死循环。

如何解决:https://www.cnblogs.com/slyfox/p/7388743.html中有提到,大家可以去看一看

使用匿名类 

使用[Newtonsoft.Json.JsonIgnore]特性标记 

直接进行配置为忽略循环引用 【推荐】

这里就不对已经有的解决方案进行过多赘述。

 

然后是个人实际遇到的问题以及自己的解决方案:

我定义了一个Node类来进行一个题库的维护,这里为了题库的路径查询方便,我定义了一个双向的方案(sonNode可以向下查找,parent可以向上查找,当然这种方案现在看比较作死,大家不要模仿)

 public class Node//节点类
    {
        public MyFiles files;//题目对象       
        public MyFolders folders;//题库对象       
        public List<Node> sonNode = new List<Node>();//记录自己直接子节点的Node      
        public Node parentFolders;//存储自己的父亲对象,路径查找由下到上        
        public bool type;//节点类型
    }

然后我就在我的Main函数中尝试对List<Node>进行序列化

 using (FileStream stream = new FileStream("FoldersGather.xml", FileMode.OpenOrCreate))
             {
                 XmlSerializer s = new XmlSerializer(typeof(List<Node>));
                 s.Serialize(stream, operation.GetFoldersGather());
                 stream.Close();
                 Console.WriteLine("序列化FoldersGather成功");
             }

这个时候就产生了异常,开始百思不得其解,现在看来虽然我只有一个类,但是我犯的错误和开头举例是相同的,父类中的List指向子类,子类的parent指向父类,于是产生了循环引用。

暂时没有实践大佬们的解决方案,我个人的当时的解决思路就是上到下,和下到上查找只保留一个,这样循环引用的问题就没有了,因为引用是完全单向了,这里一个小注意事项:我开始保留的是parent,但是我的根节点的parent指向自己,这里构成了一个自环也会循环引用,还好调试的时候看出来了,不然要把自己坑得很惨。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值