我在使用protobuf-net进行反序列化时遇到问题。
我有以下课程:
[ProtoContract]
public class CrazyList : List<string>
{
[ProtoMember(1)]
private readonly string _foo;
public CrazyList(string foo)
{
_foo = foo;
}
public CrazyList(){}
public new void Add(string item)
{
Console.Write(item + foo); // Problem is here!
base.Add(item);
}
}
并像这样使用:
var list = new CrazyList("world!");
list.Add("Hello ");
using (var ms = new MemoryStream())
{
Serializer.Serialize(ms, list);
ms.Position = 0;
var listDS = Serializer.Deserialize<CrazyList>(ms);
listDS.Add("Goodbye ");
}
方法Add
在_foo
字段反序列化完成之前被激发。
我该如何解决这个问题?
您需要将其用于CrazList属性;
[ProtoBuf.ProtoContract(IgnoreListHandling=true)]
与XmlSerializer一样,要么是列表,要么是叶。不存在"两者皆有"。目前,它将检测"列表",并且不会查找叶成员。您可以将其更改为叶子(请参阅Fredou的回答),但它不会序列化这些项。
由于有线规范(由谷歌而非我)的原因,列表本身没有表示:重复的序列只是:"项,项,项"。因此,如果某个东西是一个列表,那么我就无法存储与列表本身相关的数据。
坦率地说,最简单的选择是重构以封装,例如(为了简洁起见,尽量减少):
class SomeWrapper {
string Foo ...
List<string> Items ...
}
如果你需要的话,你也可以作弊,方法是使用Fredou展示的方法,并添加:
[ProtoMember(2)]
private IList<string> Items { get { return this; } }
这将使其看起来像上面的最小示例,而不会以任何显著的方式实际更改模型。
顺便说一句:不建议为List<T>
子类提供自定义Add,并且不应依赖反序列化的顺序。