Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ProtoBuf net忽略“IgnoreListHandling”_C#_Serialization_Protocol Buffers_Protobuf Net - Fatal编程技术网

C# ProtoBuf net忽略“IgnoreListHandling”

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

我有一个名为ConfigNode的树结构类,类似于SerializationInfo,它可以在列表中存储配置值并控制子节点。当我添加IEnumerable作为要派生的接口时,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等。配置值本身将添加到一个不重要的存储方法中。它将对象作为参数,并尝试将类型强制转换为可存储数据类型之一,并将其存储为强类型原语代理。实体基类只提供一个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;
        }
    }
}