protobuf.net没有序列化零

时间:2009-09-04 13:38:12

标签: .net serialization protobuf-net

看起来像Int64有0的编码问题。其他值为Int64 ok。

[ProtoMember(3)] private readonly Int64 _intValue

被反序列化为Int64.MinValue

有什么想法吗?

我确认了这个错误。如果_val == 0

,此类将无法正确序列化

[ProtoContract]

class VerySimple
{
    [ProtoMember(1)]
    private readonly Int64 _val = Int64.MinValue;

    public VerySimple(long val)
    {
        _val = val;
    }

    public long Val
    {
        get { return _val; }            
    }

    public VerySimple()
    {
    }
}

此测试失败

[测试]

    public void TestProtobufEncodingSimple()
    {
        //OK
        {
            MemoryStream stream = new MemoryStream();
            Serializer.Serialize(stream, new VerySimple(1));
            stream.Seek(0, SeekOrigin.Begin);
            VerySimple reloaded = Serializer.Deserialize<VerySimple>(stream);
            Assert.AreEqual(reloaded.Val, 1L);
        }

        //KO
        {
            MemoryStream stream = new MemoryStream();
            Serializer.Serialize(stream, new VerySimple(0));
            stream.Seek(0, SeekOrigin.Begin);
            VerySimple reloaded = Serializer.Deserialize<VerySimple>(stream);
            Assert.AreEqual(reloaded.Val, 0L);
        }
    }

1 个答案:

答案 0 :(得分:1)

抱歉延迟了 - 我离线了几天;-p

协议缓冲区规范在大多数类型上的隐式默认值为零。为确保合规处理,除​​非另有说明,否则它将遵守此默认值。我将尝试在文档中更清楚地说明这一点。

有几种解决方案:

  • 在字段中添加[DefaultValue(int.MinValue)]属性以设置显式默认值
  • IsRequired = true添加到[ProtoMember]属性
  • 如果您使用Nullable<int>,我怀疑它会将零视为显式
  • 对于属性,它尊重ShouldSerialize*模式,因此如果Val属性(带有setter)具有[ProtoMember],则会查找bool ShouldSerializeVal()