关于继承的 ProtoBuf-Net 的问题?

Posted

技术标签:

【中文标题】关于继承的 ProtoBuf-Net 的问题?【英文标题】:Questions regarding ProtoBuf-Net with inheritance? 【发布时间】:2019-07-11 11:22:18 【问题描述】:

我想使用 protobuf 用于通过套接字连接的协议。

我的问题是关于继承的。

假设我的项目中有以下类:

    动物 猫(继承自动物) 狗(从动物继承)

假设:

    Animal 继承自 Creature,它来自 DLL 中的一个类,我无法修改其代码(假设它是第 3 方库)。 Cat 有 10 个字段,我将属性 ProtoMember 赋予 1 到 10。 Dog 包含 12 个字段,因此我将 ProtoMember 指定为 1 到 12。 Animal 有 5 个字段,因此我将 ProtoMember 指定为 1 到 5。

到目前为止一切顺利。

为了处理继承,假设我在 Cat 上使用了以下属性:

[ProtoInclude(11, typeof(Pet))]

我在 Dog 上使用:

[ProtoInclude(13, typeof(Pet))]

关于动物使用:

[ProtoInclude(6, typeof(Creature))]

问题:

    到目前为止我使用的这些数字都有效吗?如果不是,它们应该是什么?原因是什么? 我是否应该在 ProtoInclude 中给出一个空白(例如 111、113 和 106),以便允许将新字段添加到这些类中?或者我是否保持数字系列紧凑并在未来需要时进行调整?

所以要处理Creature的继承(哪些代码不在我的项目中),我相信我必须使用Runtime Type声明(这里提到:protobuf-net inheritance)

我不太确定这个示例需要哪些语句,以及这些语句需要放在我的项目中的什么位置?

任何帮助将不胜感激。谢谢。

【问题讨论】:

【参考方案1】:

[ProtoInclude] 从基类到子类-您需要注释 base 类型-因此:需要为@987654324 声明[ProtoInclude(...)] 标记的Pet @ 和 Dog。同样,Creature 需要声明它需要Animal。显然,如果您不控制Creature,这是一个问题,但是如果这是一个问题,则可以在运行时通过RuntimeTypeModel 配置此。就个人而言,我不建议使用您无法在序列化层次结构中控制的类型。

但是对于你的问题:

    没关系,只要不与声明类型上的其他数字冲突即可;越低越便宜(12 编码比 34134923 便宜) 完全由您决定;常规字段和子类型字段是否交错无关紧要,所以没有问题
[ProtoInclude(4, Whatever)]
[ProtoInclude(7, WhateverElse)]
class Foo 
   [ProtoMember(1, ...)] ...
   [ProtoMember(2, ...)] ...
   [ProtoMember(3, ...)] ...
   [ProtoMember(5, ...)] ...
   [ProtoMember(6, ...)] ...
   [ProtoMember(8, ...)] ...

但我承认很多人更喜欢将这两个分开 - 也许

[ProtoInclude(101, Whatever)]
[ProtoInclude(102, WhateverElse)]
class Foo 
   [ProtoMember(1, ...)] ...
   [ProtoMember(2, ...)] ...
   [ProtoMember(3, ...)] ...
   [ProtoMember(4, ...)] ...
   [ProtoMember(5, ...)] ...
   [ProtoMember(6, ...)] ...

【讨论】:

感谢您的回复。 RuntimeTypeModel 的语句应该写在哪里?我的模型类在一个库 DLL 项目中,而该项目又被其他库 DLL 项目和服务器项目(Windows 服务和 Web 服务)使用。? @millie 这就是为什么我不建议一开始就这样做 :) 如果你是链条的一端(最底部或最顶部),你可以让它工作得足够好) - 但如果你在中间,它会变成一个巨大的痛苦。可以做到,但是:这将比它的价值更痛苦。 IMO,认真考虑尽一切努力根本不需要它 - 通过不混合域模型和序列化模型。我的意思是:当它变得混乱时,序列化您控制的内部类型 - 将它们单独映射到public模型。跨度>

以上是关于关于继承的 ProtoBuf-Net 的问题?的主要内容,如果未能解决你的问题,请参考以下文章

限制 protobuf-net 继承“树”

使用protobuf-net继承时如何选择字段号?

用于继承的 Protobuf-net .proto 文件生成

如何停止使用 Protobuf-Net 继承,直接使用继承类?

Protobuf-net.Grpc 服务契约继承

protobuf-net 中的对象继承