How are int ProtoMember / ProtoInclude separated / placed in ProtoBuf?

I have a couple of questions about how / where the identifier should be declared [ProtoContract]

.

Imagine the following code:

[ProtoContract]
[ProtoInclude(100, typeof(SomeClassA))]//1) CAN I USE 1 here?
public abstract class RootClass{
    [ProtoMember(1)]
    public int NodeId {get;set;}
}

[ProtoContract]
[ProtoInclude(200, typeof(SomeClassC)]//2) Should I declare this here or directly on the RootClass?
//3) Can I use the id 100 here?
//4) Can I use the id 1 here? or member + include share the id?
public class SomeClassA : RootClass{

    [ProtoMember(1)]//5) CAN I USE 1 here? Since the parent already use it but it a different class
    public String Name{get;set;}
}

[ProtoContract]
public class SomeClassC : SomeClassA {
    [ProtoMember(2)]
    public int Count{get;set;}
}

[ProtoContract]
public class SomeClassD : SomeClassA {
    [ProtoMember(2)] //6) Can I use 2 here? Since SomeClassC already use it and is a sibling?
    public int Count{get;set;}
}

      

I have posed several questions with questions:

  • CAN I USE 1 here?
  • Should I declare this here or directly on the RootClass?
  • Can I use ID 100 here?
  • Can I use ID 1 here? or member + enable id sharing?
  • CAN I USE 1 here? Since the parent is already using it, but it is different from the class
  • Can I use 2 here? Since SomeClassC is already using it and is a sibling?

The thing is, we have a huge model with a lot of classes that all inherit from the same object, so I'm trying to figure out which ID I should take care of.

+3


source to share


1 answer


Short version:

  • the set of field numbers for a type is union numbers defined against members (fields and properties), and numbers defined for immediate subtypes (includes)
  • the set of field numbers must be unique within , for one type - no need to consider basic types or derived types

Longer version:

The reason for this is that subtypes essentially appear 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;}
}

      

has the syntax 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;
}

      



Note that at most 1 subtype field will be used, so it can be read oneof

for purposes .proto

. Any fields related to the subtype will be included in message SomeClassA

, so there is no conflict with RootClass

, and they do not have to be unique. The numbers should be unique only for message

the sense .proto

.


To ask specific questions, follow these steps:

  • no, because it would contradict NodeId

  • it must be declared on SomeClassA

    ; protobuf-net only expects immediate descendants and keeps the numbering consistent and easy to read, since the field number is only required to be consistent with membersSomeClassA

  • Yes, you can; no conflict
  • no, because it would contradict Name

  • Yes, you can; no conflict
  • Yes, you can; there is no conflict, but in fact protobuf-net does not even think of SomeClassD

    as a sibling (he never advertised as include), but if SomeClassA

    was [ProtoInclude(201, typeof(SomeClassD))]

    , then it would be good. This will modify ours .proto

    to add:

    optional SomeClassD _alsoNotNamed = 201;
    
          

    before message SomeClassA

    and add:

    message SomeClassD {
        optional int32 Count = 2;
    }
    
          


Note that protobuf-net does not actually generate syntax .proto

unless you explicitly ask for it (via GetSchema<T>

, etc.). I am including it solely for illustrative purposes in terms of basic protobuf concepts.

+4


source







All Articles