如本文所述,我们可以使用ProtoInclude属性来管理类层次序列化。如果我们只使用protobuf-net,它在两个方向上都能很好地工作。但是当我们试图反序列化消息时,问题发生了,由"外部"遗留协议缓冲区实现序列化,例如Java等。
如上所述,当子类字段在父类字段之前序列化时,Protobuf-net通过"反向"字节序列识别类层次结构。但是遗留代码以"适当的"顺序序列化它们,并且protobuf-net抛出一个"无法将类型'A'的对象转换为类型'B'"。反序列化过程中的异常。相反,它工作得很好,遗留代码可以反序列化由protobuf-net库产生的"分层"消息。
I不能影响管道另一侧的字节序列化顺序。如何在。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:
- 序列化和反序列化返回原始类- OK
- 序列化和反序列化回生成的类- OK
- 序列化原始并反序列化为生成的 - OK
- 序列化生成的并反序列化为原始 - FAIL, "无法将类型'A'的对象转换为类型'B'。"异常
我研究了生成的字节,发现了一个差异——字节顺序。
示例:let Age=10 and Balls=23。然后:
- original B serialized:[82,2,16,23,8,10],可以使用original和生成的类来反序列化;
- 生成的 B序列化:[8,10,82,16,23],不能使用上面的protobuf-net 原始类反序列化。
我希望现在它足够清楚,并希望得到积极的答案:是的,有一种方法来使用ProtoInclude和反序列化泛型类。
编辑:这应该在r616以后的v2中得到支持。
引用protobuf/java教程:
所以:无论你在本地使用了什么来欺骗本地继承,我都会建议:在这里也使用它。例如,您可以通过protogen运行现有的.proto。不要去寻找类似于类继承的工具,尽管-协议缓冲区不会这样做。
如果你能非常具体地说明两边的布局(例如一个样本。proto),我可能会进一步建议。