更新时间:2023-02-17 15:22:55
简短版本:
更长的版本:
这样做的原因是子类型本质上被映射为可选字段:
The reason for this is that subtypes are essentially mapped as optional fields:
[ProtoContract]
[ProtoInclude(100, typeof(SomeClassA))]
public abstract class RootClass{
[ProtoMember(1)]
public int NodeId {get;set;}
}
[ProtoContract]
[ProtoInclude(200, typeof(SomeClassC)]
public class SomeClassA : RootClass{
[ProtoMember(1)]
public String Name{get;set;}
}
[ProtoContract]
public class SomeClassC : SomeClassA {
[ProtoMember(2)]
public int Count{get;set;}
}
是,就 proto2
语法而言:
message RootClass {
optional int32 NodeId = 1;
optional SomeClassA _notNamed = 100;
}
message SomeClassA {
optional string Name = 1;
optional SomeClassC _notNamed = 200;
}
message SomeClassC {
optional int32 Count = 2;
}
请注意,最多会使用 1 个子类型字段,因此可以将其视为 oneof
用于 .proto
的目的.message SomeClassA
中会包含与子类型相关的任何字段,因此与 RootClass
没有冲突,它们不需要唯一.在 .proto
意义上,每个 message
的数字只需要是唯一的.
Note that at most 1 sub-type field will be used, so it can be considered oneof
for the purposes of .proto
. Any fields relating to the sub-type will be included in message SomeClassA
, so there is no conflict with RootClass
and they do not need to be unique. The numbers only need to be unique per message
in the .proto
sense.
要回答具体问题,然后:
To take the specific questions, then:
NodeId
SomeClassA
上声明;protobuf-net 只期待直接后代,它保持编号一致且便于阅读,因为字段编号只需要与 SomeClassA
Name
是的,你可以;没有冲突 - 尽管实际上 protobuf-net 甚至不会将 SomeClassD
视为兄弟反正(它没有在任何地方作为包含进行宣传) - 但如果有是 [ProtoInclude(201, typeof(SomeClassD))]
在 SomeClassA
上,然后就可以了.这将更改我们的 .proto
以添加:
NodeId
SomeClassA
; protobuf-net is only expecting immediate descendants, and it keeps the numbering consistent and conveniently readable, since the field number is only required to not conflict with the members of SomeClassA
Name
yes you can; there is no conflict - although actually protobuf-net won't even think of SomeClassD
as a sibling anyway (it isn't advertised anywhere as an include) - but if there was a [ProtoInclude(201, typeof(SomeClassD))]
on SomeClassA
, then it would be fine. This would change our .proto
to add:
optional SomeClassD _alsoNotNamed = 201;
给消息SomeClassA
,并添加:
message SomeClassD {
optional int32 Count = 2;
}
请注意,protobuf-net 不会实际上生成 .proto
语法,除非您明确要求(通过 GetSchema
等) - 我将它包含在内纯粹是为了说明底层 protobuf 概念.
Note that protobuf-net doesn't actually generate the .proto
syntax unless you explicitly ask for it (via GetSchema<T>
etc) - I'm including it purely for illustrative purposes in terms of the underlying protobuf concepts.