C# 检测到Protobuf net可能的递归:序列化子级和父级
一般来说,我对序列化还不熟悉,甚至对protobuf还比较新。这是我的问题,我有以下课程: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; }
[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;
}
}
}