检测到 Protobuf-net 可能的递归:序列化孩子和父母

Posted

技术标签:

【中文标题】检测到 Protobuf-net 可能的递归:序列化孩子和父母【英文标题】:Protobuf-net possible recursion detected: serialize children and parents 【发布时间】:2012-08-27 13:29:52 【问题描述】:

一般来说,我是序列化的新手,甚至对 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>();
    


[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>();
    

尝试序列化时,我收到“检测到可能的递归”错误。

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

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

【问题讨论】:

我的猜测是给定节点包含指向子节点的指针,而子节点又具有指向父节点的指针,从而创建循环引用。因此可能递归检测到错误。 @Ankush 问题已解决,感谢帮助 【参考方案1】:

我找到了解决办法:我不序列化父母,在“Controle”类中反序列化后使用这个函数:

    [ProtoAfterDeserialization]
    protected void OnDeserialized()
    
        if (ControlesInternes.Count > 0)
        
            foreach (var ctl in ControlesInternes)
            
                ctl.Parent = this;
            
        
    

【讨论】:

可能想在 ControlesInternes 上添加一个空检查,但本质上:是的,应该这样做

以上是关于检测到 Protobuf-net 可能的递归:序列化孩子和父母的主要内容,如果未能解决你的问题,请参考以下文章

使用 ProtoBuf-Net 进行两组不同的序列化

序列化动态类型参数 Protobuf-net

protobuf-net:不正确的线型反序列化 TimeSpan

在 protobuf-net 中序列化 IEnumerable

使用 Protobuf-net 反序列化二进制文件时的线型无效

使用 protobuf-net 反序列化字典