protobuf-net:继承自定义集合

本文关键字:集合 自定义 继承 protobuf-net | 更新日期: 2023-09-27 18:16:42

我有一个自定义集合,这是一个封装List<>的简单实现:

[DebuggerDisplay("Count = {Count}")]
[Serializable()]
[ProtoInclude(100, typeof(SimpleTreeNodeList<>))]
public class SimpleList<T> : IList<T>, ICollection<T>, IEnumerable<T>, ICollection
{
  ... all methods redirect to a private List<T> ...
}

这样做的原因是我需要重写Add方法,这对于标准的List是不可能的。我需要创建一个树,集合包含一个子列表。当在集合中添加元素时,我需要将其绑定到父元素。

我继承了SimpleTreeNodeList<>

中的SimpleList<T>

如果我序列化/反序列化一个SimpleList<T>,它就像一个魅力。
但是,如果序列化/反序列化SimpleTreeNodeList<T>,则无法工作:没有错误,但反序列化时集合为空。

我不明白为什么,至于其他类型,它可以正常工作?
我读过,我必须在基类上设置ProtoInclude属性,这就是我所做的,但仍然是同样的问题

这是实现代码:

[CollectionDataContract(IsReference = true)]
[Serializable]
[ProtoContract]
public class SimpleTreeNodeList<T> : SimpleList<SimpleTreeNode<T>>
{
    #region CTor
    public SimpleTreeNodeList()
        : base()
    {
    }
    public SimpleTreeNodeList(int capacity)
        : base(capacity)
    {
    }
    public SimpleTreeNodeList(SimpleTreeNode<T> parent)
    {
        this.Parent = parent;
    }
    #endregion
    [IgnoreDataMember]
    [ProtoMember(1, AsReference = true)]
    public SimpleTreeNode<T> Parent { get; set; }

    public override void Add(SimpleTreeNode<T> node)
    {
        base.Add(node);
        node.Parent = Parent;
    }
    public void AddRange(IEnumerable<SimpleTreeNode<T>> collection) 
    {
        foreach (var node in collection)
            this.Add(node);
    }

    public override void Insert(int position, SimpleTreeNode<T> node)
    {
        base.Insert(position, node);
        node.Parent = this.Parent;
    }
    public override void InsertRange(int position, IEnumerable<SimpleTreeNode<T>> nodes)
    {
        base.InsertRange(position, nodes);
        foreach (var node in nodes)
            node.Parent = this.Parent;
    }
    public SimpleTreeNode<T> Add(T Value)
    {
        SimpleTreeNode<T> node = new SimpleTreeNode<T>(Parent);
        node.Value = Value;
        base.Add(node);
        return node;
    }
    public void Sort(Comparison<T> comparison)
    {
        this.Sort((x, y) => comparison(x, y));
    }
    public override string ToString()
    {
        return "Count=" + Count.ToString();
    }
}
我的简单测试用例:
[Test]
public void TestSimpleTreeNodeListSerialization()
{
    var data = new SimpleTreeNodeList<string>();
    data.Add("Un");
    data.Add("Deux");
    data.Add("Trois");
    var path = Path.GetTempFileName();
    try
    {
        File.WriteAllBytes(path, serialize(data));
        var data2 = deserialize<SimpleTreeNodeList<string>>(File.ReadAllBytes(path));
        Assert.IsNotNull(data2);
        Assert.AreEqual(3, data2.Count);
        for (int i = 0; i < data.Count; i++)
        {
            Assert.AreEqual(data[i].Value, data2[i].Value);
        }
    }
    finally
    {
        if (File.Exists(path))
            File.Delete(path);
    }
}

private byte[] serialize<T>(T data)
{
    var formatter = Serializer.CreateFormatter<T>();
    using (var stream = new System.IO.MemoryStream())
    {
        formatter.Serialize(stream, data);
        return stream.ToArray();
    }
}
private T deserialize<T>(byte[] data)
{
    var formatter = Serializer.CreateFormatter<T>();
    using (var stream = new System.IO.MemoryStream(data))
    {
        return (T)formatter.Deserialize(stream);
    }
}

protobuf-net:继承自定义集合

我也遇到过同样的问题。如果将DebuggerDisplay中的表达式更改为constant,则它可以工作。从[DebuggerDisplay("{Object.Property}")来[DebuggerDisplay("test"]