如何修复圆形序列化时检测到圆形参考?

时间:2014-02-03 12:56:16

标签: c# serialization circular-dependency

我正在尝试使用下面提供的对象序列化树结构。我需要使用对象序列化的子列表,但我可以在没有父对象的情况下生存(因为我可以在解串行化时修复它)。

我遇到的问题是,无论我是否[XmlIgnore],我仍然会收到此错误。

  

在序列化类型的对象时检测到循环引用   '的DataEntry'

如果我更改'Parent'属性的'getter / setter'什么也不做,那一切都有效。

[XmlIgnore]
        public DataEntry Parent 
        {
            get { return null; }
            set {} 
        }

但我需要在稍后阶段提供此父参考。

public class DataEntry
    {
        [XmlIgnore]
        public DataEntry Parent { get; set; }

        public List<DataEntry> Children { get; set; }

        private List<String> mValues = new List<String>();
        public List<String> Values
        {
            get
            {
                return mValues;
            }
            set
            {
                mValues = value;
            }
        }

        private String mName = String.Empty;
        public String Name
        {
            get { return mName; }
            set
            {
                mName = value;
            }
        }

        /// <summary>
        /// Data entry
        /// </summary>
        /// <param name="partent">parent node - if root node give no parent</param>
        /// <param name="name">Name of property</param>
        /// <param name="values">Values for this property</param>
        public DataEntry(DataEntry partent, String name, List<String> values)
        {
            Children = new List<DataEntry>(); 
            Parent = partent;
            mValues = values;
            mName = name;
        }

        /// <summary>
        /// Add a child to this node
        /// </summary>
        /// <param name="child"></param>
        public void AddChild(DataEntry child)
        {
            Children.Add(child);
        }
    }

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

XML具有树结构(嵌套标签)。您的对象以图形形式连接(即循环)。

您必须访问图表,查找周期并通过剪切参考来打开它们。 获得图表的生成树后,您可以将其序列化。

但是剪辑的引用将会丢失。 因此,除了生成树之外,您还希望将剪切的引用存储起来。

反序列化后,您需要反序列化生成树,然后再剪切其他引用。因此,您将通过在对象之间重新建立它们来重建这些引用。

如果可以,请尝试通过将图表中的周期缩减到已定义的生成树来避免周期。这样,您就不必为了序列化它而完成所有工作。

另一方面,删除这些引用可能会影响应用程序的其余部分,因此您可能不希望这样做。

另一方面:设计良好的数据库有一个normal form(通常是第三个​​,但也有其他的)。这些概念彼此非常相关。

这是一个粗略的伪C#指南:

xml = serialize(root)
{
    1. set all parents to null
    2. XML serialize
    3. rebuilt all parents <-- reuse rebuiltParents()
}

root = deserialize(xml)
{
    1. XML deserialize
    2. rebuilt all parents <-- reuse rebuiltParents()
}