使用java和protobuf-net的协议缓冲区进行序列化时,为什么byte []不同?

时间:2014-02-04 11:04:49

标签: c# java protocol-buffers zeromq protobuf-net

当我用Java中的协议缓冲区序列化这个对象时,我得到了这个字节数组:

byte[] topic = Transport.newBuilder()
            .setTopic(Topics.ORD)
            .setExtension(Ord.command, Commands.INSERT)
            .build()
            .toByteArray();

// [8,2,16,0]

当我使用protobuf-net做同样的事情时,我得到了这个

var transport = new Transport
{
    topic = Topics.ORD,
    command = Commands.INSERT
};

var stream = new MemoryStream();
Serializer.Serialize(stream, transport);
byte[] result = stream.ToArray(); // [8,2]

使用zmq和基于bye数组的订阅时,这会给我带来一些麻烦。 我怎样才能确保两个阵列看起来都一样?

1 个答案:

答案 0 :(得分:3)

protobuf-net,在v1中,做出了“零默认值”假设。如果我从头开始,可能不会再做出决定,确实可以在v2中禁用此行为。但就目前情况而言,在许多情况下,它假定零作为隐含默认值。我猜你的command是一个不可为空的枚举,在这种情况下它将应用这个逻辑(作为旁注:如果它是可以为空的,它会这样做 - 它会使用null检查包含/排除决定。)

因此,它决定不需要序列化第二个字段(字段编号2,编码为varint)。因此没有[16, 0]

选项:

  • 使用可空成员(相当于optional) - 即public SomeEnum? Command {get;set;}
  • 将该成员标记为 required IsRequired=true上的ProtoMemberAttribute
  • 关闭隐式零默认行为(UseImplicitZeroDefaults实例上的RuntimeTypeModel