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

时间:2011-11-11 11:54:40

标签: .net inheritance protocol-buffers protobuf-net

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类:

  • 序列化和反序列化原始类 - 确定
  • 序列化和反序列化生成的类 - 确定
  • 序列化原始并反序列化为生成 - 确定
  • 序列化生成的并反序列化为原始 - 失败“无法将”A“类型的对象投射到”B“类型'。“例外

我调查了结果字节并发现了差异 - 字节顺序

示例:让Age = 10,Balls = 23。然后:

  • 原始 B序列化:[82,2,16,23,8,10],可以使用原始作为生成班级;
  • 生成 B序列化:[8,10,82,2,16,23],不能使用上面的protobuf-net 原始类反序列化。

我希望现在已经足够清楚了,并希望得到肯定答案:是的,有一种方法可以使用ProtoInclude和反序列化泛型类。

1 个答案:

答案 0 :(得分:2)

编辑:从r616开始,这应该在v2中得到支持。


引用protobuf / java tutorial

  

不要去寻找类似于类继承的工具,但协议缓冲区不会这样做。

所以:无论你在本地使用什么欺骗本地的继承,我都会建议:在这里使用它。例如,您可以通过protogen运行现有的.proto。

如果您对双方的布局非常具体(例如样本.proto),我可能会进一步建议。