2009-09-04 62 views
2

它看起来像Int64有一个0的编码问题。其他值为Int64 ok。protobuf.net不是序列化零

[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

抱歉耽搁这个类将无法正常连载 - 我有一个离线几天; -p

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

有几种解决方案:

  • 添加[DefaultValue(int.MinValue)]属性字段设置明确的默认
  • 添加IsRequired = true[ProtoMember]属性
  • 如果使用Nullable<int>,我怀疑这将把零作为显式
  • 在属性的情况下,它遵守ShouldSerialize*模式,所以如果Val属性(使用setter)具有[ProtoMember],它会寻找bool ShouldSerializeVal()