C# ProtoBuf net忽略“IgnoreListHandling”
我有一个名为ConfigNode的树结构类,类似于SerializationInfo,它可以在列表中存储配置值并控制子节点。当我添加IEnumerable作为要派生的接口时,protobuf net在序列化过程中失败,并导致StackOverFlowException,即使IgnoreListHandling标志设置为true也是如此C# ProtoBuf net忽略“IgnoreListHandling”,c#,serialization,protocol-buffers,protobuf-net,C#,Serialization,Protocol Buffers,Protobuf Net,我有一个名为ConfigNode的树结构类,类似于SerializationInfo,它可以在列表中存储配置值并控制子节点。当我添加IEnumerable作为要派生的接口时,protobuf net在序列化过程中失败,并导致StackOverFlowException,即使IgnoreListHandling标志设置为true也是如此 [Serializable, DataContract, ProtoContract(IgnoreListHandling = true)] public cla
[Serializable, DataContract, ProtoContract(IgnoreListHandling = true)]
public class ConfigNode : Entity, ICloneable, INotifyPropertyChanged
{
[DataMember, ProtoMember(1)]
private Dictionary<String, PrimitiveSurrogate> values = new Dictionary<String, PrimitiveSurrogate>();
private Dictionary<String, ConfigNode> _Childs = new Dictionary<String, ConfigNode>();
[DataMember, ProtoMember(2)]
public Dictionary<String, ConfigNode> Childs
{
get
{
return _Childs;
}
private set
{
_Childs = value;
}
}
[DataMember, ProtoMember(3)]
public ConfigNode Parent { get; set; }
}
工作正常。PrimitiveSurrogate是一个结构,它存储所有常用的几乎是原语的可空值,如String、Guid、DataTime、float/double、bool、char等。配置值本身将添加到一个不重要的存储方法中。它将对象作为参数,并尝试将类型强制转换为可存储数据类型之一,并将其存储为强类型原语代理。实体基类只提供一个Name属性,其他什么都不提供
但是,只要我将IEnumerable添加到接口列表并添加下面所示的适当方法,任何序列化尝试都会抛出StackOverflowException
public void Add(ConfigNode child)
{
if (child == null)
throw new ArgumentNullException("child");
if (child.Name == null)
throw new ArgumentException("The child's name was null. The child cannot be added.");
child.Parent = this;
lock (this.Childs)
{
this.Childs[child.Name] = child;
}
}
public IEnumerator<ConfigNode> GetEnumerator()
{
lock (this.Childs)
{
return this.Childs.Values.Clone().GetEnumerator();
}
}
IEnumerator IEnumerable.GetEnumerator()
{
lock (this.Childs)
{
return this.Childs.Values.Clone().GetEnumerator();
}
}
克隆是一种扩展方法,如下所示:
public static IEnumerable<T> Clone<T>(this IEnumerable<T> collection)
{
return collection.ToList();
}
protobuf net似乎忽略了IgnoreListHandling标志,有人能帮忙吗?没关系,我发现了错误。在一些更改之后,我在Childs属性和Childs.get中引入了锁,我锁定的是属性本身,而不是backing字段。这导致StackOverflow,因为Monitor类尝试访问该属性并导致再次访问get访问器 它现在可以顺利地反序列化 固定版本:
[DataMember, ProtoMember(2)]
public Dictionary<String, ConfigNode> Childs
{
get
{
lock (_Childs)
{
return _Childs;
}
}
private set
{
lock (_Childs)
{
_Childs = value;
}
}
}