C# 检测到Protobuf net可能的递归:序列化子级和父级

C# 检测到Protobuf net可能的递归:序列化子级和父级,c#,protocol-buffers,protobuf-net,C#,Protocol Buffers,Protobuf Net,一般来说,我对序列化还不熟悉,甚至对protobuf还比较新。这是我的问题,我有以下课程: [ProtoContract] class Controle { [ProtoMember(1, AsReference=true)] public HashSet<Controle> ControlesInternes { get; set; } [ProtoMember(2)] public string TypeControle { get; set; }

一般来说,我对序列化还不熟悉,甚至对protobuf还比较新。这是我的问题,我有以下课程:

[ProtoContract]
class Controle
{
    [ProtoMember(1, AsReference=true)]
    public HashSet<Controle> ControlesInternes { get; set; }
    [ProtoMember(2)]
    public string TypeControle { get; set; }
    [ProtoMember(3)]
    public Dictionary<string, string> Attributs { get; set; }
    [ProtoMember(4)]
    public int Ligne { get; set; }
    [ProtoMember(5)]
    public string InnerText { get; set; }
    [ProtoMember(6)]
    public Controle Parent { get; set; }

    public Controle()
    {
        ControlesInternes = new HashSet<Controle>();
        Attributs = new Dictionary<string, string>();
    }
}
[协议]
班级管理
{
[原成员(1,AsReference=true)]
公共HashSet控制中心{get;set;}
[原成员(2)]
公共字符串TypeControle{get;set;}
[原成员(3)]
公共字典属性{get;set;}
[原成员(4)]
公共内部对齐{get;set;}
[原成员(5)]
公共字符串InnerText{get;set;}
[原成员(6)]
公共控件父项{get;set;}
公共控制()
{
ControlesInternes=新哈希集();
Attributes=新字典();
}
}

[协议(SkipConstructor=true)]
类PageAspx
{
[原成员(1)]
公共字符串PrefixeControlOnIlait{get;set;}
[原成员(2,AsReference=true)]
公共HashSet控件{get;set;}
私有字符串CheminTmp;
私有字符串命名器;
[原成员(3)]
公共字符串命名器
{
获取{return nomFichier;}
设置{nomFichier=value;}
}
私有弦滴度;
[原成员(4)]
公弦滴度
{
获取{return titre;}
设置{titre=value;}
}
公共页面aspx()
{ }
公共页面aspx(字符串pnomficher)
{
this.NomFichier=pnomficher;
this.controlles=new HashSet();
}
}
当尝试序列化时,我得到一个“检测到可能的递归”错误

但基本上,我的代码列出了aspx页面中的所有控件,它们是层次结构(子级、父级)。这意味着在生成“PageAspx”对象之后,它包含页面的所有控件,对于每个控件,它的父控件和子控件(如果有的话)。当我没有序列化成员
ControlesInternes
时,序列化进行得很顺利。但我需要这些信息


如何使用protobuf保存这些数据?

我找到了一个解决方案:我不序列化父级,在“Controle”类中反序列化后使用此函数:


我的猜测是,给定的节点包含指向子节点的指针,而子节点又包含指向父节点的指针,从而创建循环引用。因此,可能的递归检测到错误。@Ankush问题已解决,感谢您的帮助。您可能希望在ControlesInternes上添加空检查,但本质上是:是的,应该这样做
[ProtoContract(SkipConstructor=true)]
class PageAspx
{

    [ProtoMember(1)]
    public string PrefixeControleOnilait { get; set; }
    [ProtoMember(2, AsReference = true)]
    public HashSet<Controle> Controles { get; set; }

    private string CheminTmp;

    private string nomFichier;

    [ProtoMember(3)]
    public string NomFichier
    {
        get { return nomFichier; }
        set { nomFichier = value; }
    }

    private string titre;
    [ProtoMember(4)]
    public string Titre
    {
        get { return titre; }
        set { titre = value; }
    }


    public PageAspx()
    { }

    public PageAspx(string pNomFichier)
    {
        this.NomFichier = pNomFichier;

        this.Controles = new HashSet<Controle>();
    }
}
    [ProtoAfterDeserialization]
    protected void OnDeserialized()
    {
        if (ControlesInternes.Count > 0)
        {
            foreach (var ctl in ControlesInternes)
            {
                ctl.Parent = this;
            }
        }
    }