【发布时间】:2013-12-04 12:21:54
【问题描述】:
我有一个名为ConfigNode(类似于SerializationInfo)的树结构类,它可以将配置值存储在列表中并控制子节点。当我添加IEnumerable<ConfigNode> 作为派生接口时,protobuf-net 在序列化期间失败并导致 StackOverFlowException,即使 IgnoreListHandling 标志设置为 true。
[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 等)的可空值的结构。配置值本身将添加到“Store”方法中,该方法是 no重要性。它将一个对象作为参数,并尝试将类型转换为一种可存储的数据类型,并将其存储为强类型 PrimitiveSurrogate。实体基类只提供一个名称属性,没有别的。
但只要我将IEnumerable<ConfigNode> 添加到接口列表并添加适当的方法(见下文),任何序列化尝试都会引发 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 标志,有人可以帮忙吗?
【问题讨论】:
标签: c# serialization protocol-buffers protobuf-net