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