关于继承的 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 .proto 文件生成