关于带有继承的 ProtoBuf-Net 的问题?
Questions regarding ProtoBuf-Net with inheritance?
我想使用 protobuf 来通过套接字连接使用协议。
我的问题是关于继承的。
假设我的项目中有以下 classes:
- 动物
- 猫(继承自动物)
- 狗(继承自动物)
假设:
- Animal 继承自 Creature,它来自 DLL 中的 class,我无法修改其代码(假设它是第 3 方库)。
- Cat 有 10 个字段,我为其赋予属性 ProtoMember 1 到 10。
- 狗有 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),以便它允许将新字段添加到那些 classes 中?或者我是否保持数字序列紧凑并在将来需要时进行调整?
所以要处理Creature的继承(我的项目中没有代码),我相信我必须使用Runtime Type declaration(如这里所述:protobuf-net inheritance)
我不太确定此示例需要哪些语句,以及这些语句需要放在项目中的什么位置?
任何帮助将不胜感激。谢谢。
[ProtoInclude]
从 base-class 到 sub-class - 你需要注释 base 类型 - 所以:它将是 Pet
需要为 Cat
和 Dog
声明 [ProtoInclude(...)]
标记。同样,Creature
需要声明它期望 Animal
。显然,如果您不控制 Creature
,这是一个问题,但如果这是一个问题,则可以在运行时通过 RuntimeTypeModel
配置此 。就个人而言,我不建议使用您在序列化层次结构中无法控制的类型。
但是对于你的问题:
- 没关系,只要不和声明类型上的其他数字冲突即可;越低越便宜(
12
比 34134923
编码更便宜)
- 完全取决于你;如果常规字段和 sub-type 字段交错并不重要,所以
不是问题
[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, ...)] ...
}
我想使用 protobuf 来通过套接字连接使用协议。
我的问题是关于继承的。
假设我的项目中有以下 classes:
- 动物
- 猫(继承自动物)
- 狗(继承自动物)
假设:
- Animal 继承自 Creature,它来自 DLL 中的 class,我无法修改其代码(假设它是第 3 方库)。
- Cat 有 10 个字段,我为其赋予属性 ProtoMember 1 到 10。
- 狗有 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),以便它允许将新字段添加到那些 classes 中?或者我是否保持数字序列紧凑并在将来需要时进行调整?
所以要处理Creature的继承(我的项目中没有代码),我相信我必须使用Runtime Type declaration(如这里所述:protobuf-net inheritance)
我不太确定此示例需要哪些语句,以及这些语句需要放在项目中的什么位置?
任何帮助将不胜感激。谢谢。
[ProtoInclude]
从 base-class 到 sub-class - 你需要注释 base 类型 - 所以:它将是 Pet
需要为 Cat
和 Dog
声明 [ProtoInclude(...)]
标记。同样,Creature
需要声明它期望 Animal
。显然,如果您不控制 Creature
,这是一个问题,但如果这是一个问题,则可以在运行时通过 RuntimeTypeModel
配置此 。就个人而言,我不建议使用您在序列化层次结构中无法控制的类型。
但是对于你的问题:
- 没关系,只要不和声明类型上的其他数字冲突即可;越低越便宜(
12
比34134923
编码更便宜) - 完全取决于你;如果常规字段和 sub-type 字段交错并不重要,所以 不是问题
[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, ...)] ...
}