Protobuf-net中的继承序列化

3

假设有一个.proto文件,内容如下:

message Base {
    string Dummy = 1
}

message Derived {
    Base Super = 1
    string Parp = 2 
}

... And some C# something like:

public class Base {
    public string Dummy;
}

public class Derived : Base {
    public string Parp
}

如何在protobuf-net中自定义序列化以实现此功能?最初我开始研究使用TypeModel并为基本MetaType调用AddSubType,但是似乎它创建了所有派生类的可选字段的Base类型定义(即与我需要的相反)。 我认为我可能能够自己遍历层次结构,但是看到TypeModel时,它似乎支持提供要反序列化的类型,但在序列化期间它使用value.GetType()。 即使这样,我也不完全清楚如何做到这一点。 我的唯一选择是使用ProtoWriter手动编写每个字段吗? 这是我目前正在尝试的,但我希望有更简单的方法。
1个回答

2
首先需要注意的是,protobuf本身不支持继承。它没有“官方”的布局。Protobuf-net将不支持您所需的序列化方式:选择子类型封装(而不是基类型封装)是为了解决几个问题,包括:
  • 满足Liskov替换原则
  • 在调用者不知道/预期序列化类型时正确工作
  • 基本上,对于除了最简单的例子之外的任何东西,都能正常工作(其中两端事先完全知道要获取哪种子类型,这在很大程度上破坏了多态性的目的)
然而,您可以手动映射DTO,以便您的DTO层根本不使用继承。

谢谢Marc...我很感激。虽然它不支持,但是使用超级指针的概念(是的,我提前知道我的消息类型),我能否使用ProtoReader/Writer自己进行反序列化? - chrism
@chrism 这取决于你愿意自己编写多少内容。ProtoReader/ProtoWriter API 提供了完全访问处理线格式的功能,但是您必须处理所有字段级别的处理 - 例如,没有 IProtoSerializable 来允许仅控制一个类型。 - Marc Gravell
还有其他建议吗?使用独立的DTO集合进行映射似乎会导致大量的内存分配,仅仅是为了将数据复制到对象中进行序列化/反序列化。 - chrism
@chrism "很多"是主观的,取决于情况;此外,作为短暂的对象,它们很可能会从gen-0中收集。我的意思是:我们不能在没有更多上下文(吞吐量等)的情况下说“很多”是否“太多”。但是:您的模型涉及多少类型(只是试图评估读者/编写器方法中涉及的代码量)。最后,特定布局的要求是什么?如果它与另一个非protobuf-net布局匹配,那么我会说:不要使用继承:使用封装来匹配所需的线路布局。 - Marc Gravell
我有一个想法,我可以稍后测试并回复你吗? - Marc Gravell
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接