Protobuf-net 中的继承:ProtoInclude 和兼容性
Posted
技术标签:
【中文标题】Protobuf-net 中的继承:ProtoInclude 和兼容性【英文标题】:Inheritance in Protobuf-net: ProtoInclude and compatibility 【发布时间】:2011-11-11 11:54:39 【问题描述】:如this post 中所述,我们可以使用ProtoInclude 属性来管理类层次结构序列化。如果我们只使用 protobuf-net,它在两个方向上都可以正常工作。但是当我们尝试反序列化由“外部”遗留协议缓冲区实现序列化的消息时会出现问题,例如。 Java等
正如上面那篇文章中提到的,当子类字段在父类之前序列化时,Protobuf-net 通过“反转”字节序列识别类层次结构。但是遗留代码以“正确”的顺序将它们序列化,并且 protobuf-net 在反序列化过程中抛出 “无法将 'A' 类型的对象转换为 'B' 类型。” 异常。相反,它工作正常,遗留代码可以反序列化 protobuf-net 库产生的“分层”消息。
我不能影响管道另一侧的字节序列化顺序。如何在 .NET protobuf-net 端正确反序列化此类消息?
更新:代码示例
在我们的最后,我们有原始的 protobuf-net 分层类:
[ProtoContract, ProtoInclude(10, typeof(B))]
public class A
[ProtoMember(1)]
public int Age;
public class B : A
[ProtoMember(2)]
public int Balls;
另一方面,类是使用 .proto 文件生成的:
message B
optional int32 balls = 2;
message A
optional int32 age = 1;
optional B b = 10;
生成类示例,我们可以使用 protobuf-net 生成器为 .NET 创建它们:
[ProtoContract]
public class A_generated
[ProtoMember(1)]
public int Age;
[ProtoMember(10)]
public B b;
[ProtoContract]
public class B_generated
[ProtoMember(2)]
public int Balls;
那么现在,让我们序列化和反序列化 B 类:
序列化和反序列化回原始类 - 好的 序列化和反序列化返回生成的类 - 好的 序列化原始并反序列化为生成 - 好的 序列化生成并反序列化为原始 - FAIL,“无法将'A'类型的对象转换为'B'类型'." 异常我调查了结果字节并发现了一个差异 - 字节顺序。
示例:让 Age=10 和 Balls=23。那么:
original B 序列化:[82, 2, 16, 23, 8, 10],可以将两者作为 original 作为 generated 类进行反序列化; 生成 B 序列化:[8, 10, 82, 2, 16, 23],不能使用上面的 protobuf-net original 类进行反序列化。我希望现在已经足够清楚,并希望得到肯定的答案:是的,有一种方法可以使用 ProtoInclude 和反序列化泛型类。
【问题讨论】:
你能更具体地介绍一下这里的场景吗?我的印象是常规的 protobuf 不包括继承。因此,它经常通过封装进行填充。此外,您可以只使用现有的 .proto 来生成模型...?很乐意提供帮助,但我想确保我的回答正确。 啊,对。我现在明白上下文了,谢谢。我明白发生了什么,以及为什么。我将在今天晚些时候进行调查,看看是否有简单的解决方法。 非常小,但是 A_generated.b 应该输入为 B_generated 吗?这并不能解决问题 - 我只是想在我的测试中保持精确...... 我花了几个小时研究这个。我同意支持是可取的(编码规范相当清楚,实现应该以任何顺序处理字段),但是实现......并不明显。完成这项工作需要相当多的努力。 谢谢,期待您的答复,希望能修复。 :) 【参考方案1】:编辑:从 r616 开始,v2 应该支持这一点。
引用protobuf / java tutorial:
不过,不要去寻找类似于类继承的工具 - 协议缓冲区不会这样做。
所以:无论您在本地使用什么来欺骗本地继承,我都会建议:在这里也使用它。例如,您可以通过 protogen 运行现有的 .proto。
如果您可以非常具体地了解两侧的布局(例如 .proto 示例),我可能会提供进一步的建议。
【讨论】:
@Alex 感谢修复;我一定是在用手机什么的以上是关于Protobuf-net 中的继承:ProtoInclude 和兼容性的主要内容,如果未能解决你的问题,请参考以下文章
Protobuf-net 中的继承:ProtoInclude 和兼容性