反序列化某些属性值时,c#protobuf-net始终为-1

时间:2012-05-06 02:50:16

标签: c# protobuf-net

我不确定这个问题是否是这个问题,或者只是这个问题,我才注意到这一点。

我创建一个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。

有人可以帮帮我吗?这个问题是我的原因还是protobuf-net的原因?感谢。

2 个答案:

答案 0 :(得分:3)

ProtoBuf不会序列化具有该类型的.NET默认值的值。这种行为是设计的,因为它使输出更紧凑。

由于它不知道你的构造函数为该字段分配了一个默认值,它会被初始化为-1(因为你有明确的代码来执行此操作)。

要避免此问题,请使用常规字段并为其指定默认值,而不是在构造函数中指定默认值。

答案 1 :(得分:3)

默认情况下。它假定零值为默认值。我对此设计选择感到遗憾,因此可以在v2中禁用它,但为了兼容性而保留。您可以在v1和v2中简单地告诉它-1是默认值:

[ProtoMember(2), DefaultValue(-1)]
public int DocNumber