Protobuf-net中的继承:ProtoInclude和兼容性



如本文所述,我们可以使用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),我可能会进一步建议。

最新更新