使用 protobuf-net 反序列化 int& 类型

Posted

技术标签:

【中文标题】使用 protobuf-net 反序列化 int& 类型【英文标题】:Deserializing int& type with protobuf-net 【发布时间】:2018-04-27 13:01:15 【问题描述】:

我正在尝试升级旧代码库的依赖项以使用 protobuf-net 2.3.7 而不是 protobuf-net 1.0

以下代码用于版本 1 并打印 2147483647

var stream = new MemoryStream();
Serializer.NonGeneric.SerializeWithLengthPrefix(stream, int.MaxValue, PrefixStyle.Base128, 1);
stream.Position = 0;

Serializer.NonGeneric.TryDeserializeWithLengthPrefix(stream, PrefixStyle.Base128, _ => typeof(int).MakeByRefType(), out var lastItem);
Console.WriteLine(lastItem);

但相同的代码不适用于 protobuf-net 2.3.7 并抛出:

未处理的异常:System.InvalidOperationException:类型不是 预期,并且无法推断出任何合同:System.Int32& at ProtoBuf.Meta.TypeModel.ThrowUnexpectedType(类型类型)在 ProtoBuf.Meta.TypeModel.TryDeserializeAuxiliaryType(ProtoReader 阅读器、DataFormat 格式、Int32 标签、Type 类型、Object& 值、 Boolean skipOtherFields, Boolean asListItem, Boolean autoCreate, Boolean insideList, Object parentListOrType) at ProtoBuf.Meta.TypeModel.DeserializeWithLengthPrefix(流源, 对象值、Type 类型、PrefixStyle 样式、Int32 expectedField、 TypeResolver 解析器, Int64& bytesRead, Boolean& haveObject, SerializationContext 上下文)在 ProtoBuf.Serializer.NonGeneric.TryDeserializeWithLengthPrefix(流 来源、PrefixStyle 样式、TypeResolver 解析器、Object& 值)

虽然异常是有道理的,但我正在尝试找到一种方法来使代码与新版本的库一起工作,而无需进行大量重构。

有什么建议吗?

编辑:

MemoryStream 序列化后包含 8 个字节: new byte[] 10,6,8,255,255,255,255,7

base64:CgYI/////wc=

【问题讨论】:

哇,这是一个边缘案例!您是否碰巧知道用于序列化的字节是什么? IE。输出的十六进制还是base-64? @MarcGravell 我现在已将流输出添加到问题中。 谢谢;这些数据很有意义,谢谢 【参考方案1】:

这从来都不是一个专门设计的场景,坦率地说,我很惊讶它曾经奏效,即使在 1.something 中也是如此,但是:这似乎奏效了:

Serializer.NonGeneric.TryDeserializeWithLengthPrefix(stream, PrefixStyle.Base128, _ => typeof(int), out var lastItem);
 Console.WriteLine(lastItem); // lastItem is a boxed int

您需要包装指针是否有特定原因?

【讨论】:

由于我们的自定义 RPC 层,我们需要一个包装的指针。每当要发出请求时,我们将参数打包到消息中并将其序列化,并对响应消息执行相同的操作。当我们反序列化响应消息时,我们使用反射并获取参数类型。升级后有两个单元测试失败,因为它们专门测试ref intout int 参数的序列化/反序列化。感谢您的回答!

以上是关于使用 protobuf-net 反序列化 int& 类型的主要内容,如果未能解决你的问题,请参考以下文章

使用 protobuf-net 反序列化字典

使用 protobuf-net 反序列化不同的列表

为啥我不能使用 ProtoBuf-Net 正确反序列化我的对象?

使用 ProtoBuf-Net,如何(反)序列化多维数组?

使用知道架构的 protobuf-net 反序列化未知对象

Protobuf-Net 总是反序列化一个空列表