C# 为什么在使用java和protobuf net的协议缓冲区序列化时,字节[]不同?
当我用Java中的协议缓冲区序列化此对象时,我得到以下字节数组:C# 为什么在使用java和protobuf net的协议缓冲区序列化时,字节[]不同?,c#,java,protocol-buffers,zeromq,protobuf-net,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网络做同样的事情时,我得到
byte[] topic = Transport.newBuilder()
.setTopic(Topics.ORD)
.setExtension(Ord.command, Commands.INSERT)
.build()
.toByteArray();
// [8,2,16,0]
当我用protobuf网络做同样的事情时,我得到了这个
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数组的订阅时,这会给我带来一些麻烦。
如何确保两个数组看起来相同?protobuf net在v1中做出了“零默认值”的假设。如果我是从零开始的话,我可能不会再做决定了,事实上,这种行为在v2中可以被禁用。但就目前情况而言,在许多情况下,它假设零是一种隐性违约。我猜您的
命令
是一个不可为空的枚举,在这种情况下,它将应用此逻辑(附带说明:如果它是可为空的,它将不会这样做-它将使用null
检查包含/排除决策)
因此,它决定第二个字段(字段编号2,编码为varint)不需要序列化。因此没有[16,0]
选项:
- 使用可为空的成员(相当于
可选的
)-即
公共SomeEnum?命令{get;set;}
- 根据需要标记成员(
上的ProtoMemberAttribute
)IsRequired=true
- 在
实例上关闭隐式零默认行为(RuntimeTypeModel
)useImplicitzFaults
[8,2176,6,0]
,在c中得到[8,2,-80,6,0]
Java@mrt181这只是因为java有符号字节,而C有无符号字节;176和-80是相同的东西(二进制10110000)