我不确定这个问题是否是这个问题,或者只是这个问题,我才注意到这一点。
我创建一个Document
类并声明protobuf-net restrict。
[ProtoContract]
public class Document
{
[ProtoMember(1)]
private Dictionary<string,string> _items;
[ProtoMember(2)]
public int DocNumber
{
get;
set;
}
public Document()
{
this.DocNumber = -1;
this._items = new Dictionary<string,string>();
}
public byte[] Serialize()
{
byte[] bytes = null;
using (var ms = new MemoryStream())
{
Serializer.Serialize(ms, this);
bytes = ms.ToArray();
ms.Close();
}
return bytes;
}
public static Document Deserialize(byte[] bytes)
{
Document obj = null;
using (var ms = new MemoryStream(bytes))
{
obj = Serializer.Deserialize<Document>(ms);
ms.Close();
}
return obj;
}
}
在测试代码中:
var doc = new Document();
doc.DocNumber = 0;
var bytes = doc.Serialize();
var new_doc = Document.Deserialize(bytes);
Console.WriteLine(new_doc.DocNumber + " vs " + doc.DocNumber);
输出消息为:-1 vs 0
。我无法相信此结果(正确的结果为0 vs 0
),因此我将doc.DocNumber = 0
更改为doc.DocNumber = 1
,
输出正确:1 vs 1
。
这个问题意味着我无法将零赋值给DocNumber
属性,在Document的constructure方法中我必须声明DocNumber属性为-1。
答案 0 :(得分:3)
ProtoBuf不会序列化具有该类型的.NET默认值的值。这种行为是设计的,因为它使输出更紧凑。
由于它不知道你的构造函数为该字段分配了一个默认值,它会被初始化为-1(因为你有明确的代码来执行此操作)。
要避免此问题,请使用常规字段并为其指定默认值,而不是在构造函数中指定默认值。
答案 1 :(得分:3)
默认情况下。它假定零值为默认值。我对此设计选择感到遗憾,因此可以在v2中禁用它,但为了兼容性而保留。您可以在v1和v2中简单地告诉它-1是默认值:
[ProtoMember(2), DefaultValue(-1)]
public int DocNumber