BaltoStar BaltoStar - 2 months ago 19
C# Question

protobuf-net : how to annotate properties of derived type?

For the latest version of

protobuf-net
(
r640
folder ), how to best annotate a
ProtoMember
that is a derived type ?

[ProtoBuf.ProtoContract(Name=@"MyBaseTypeProto")]
[Serializable]
public partial class MyBaseType: ProtoBuf.IExtensible { ... }

[ProtoBuf.ProtoContract(Name=@"MyDerivedTypeProto")]
[Serializable]
public partial class MyDerivedType : MyBaseType, ProtoBuf.IExtensible { ... }

[ProtoBuf.ProtoContract(Name=@"MyMessageProto")]
[Serializable]
public partial class MyMessage : ProtoBuf.IExtensible
{
[ProtoBuf.ProtoMember(1, IsRequired = false, Name = @"MyList", DataFormat = ProtoBuf.DataFormat.Default)]
[System.ComponentModel.DefaultValue(null)]
public List<MyDerivedType> MyList;


I've tried adding
DynamicType
property to the
ProtoMember
attribute but it's not recognized.

I require a solution where the classes can be generated from
xml defs
of
proto types
. So ideally this would be done via attributes annotated onto properties definitions.

It would seem possible to use
protogen.exe
to generate classes based on message-type defs (
.proto
files ) that include
import
statements :

package MyPackage;

import "MyDerivedTypeProto.proto";

message MyMessage{
repeated MyDerivedType MyList = 1;
}


but the
import
statements apparently have no effect on the generated C# classes (
.cs
files ) except to add a comment :

// Generated from: MyMessageProto.proto
// Note: requires additional types generated from: MyDerivedType.proto

Answer
[ProtoBuf.ProtoContract(Name=@"MyBaseTypeProto")]
[ProtoBuf.ProtoInclude(typeof(MyDerivedType), someFieldNumberUniqueInsideMyBaseType)]
public partial class MyBaseType: ProtoBuf.IExtensible { ... }

[ProtoBuf.ProtoContract(Name=@"MyDerivedTypeProto")] { ... }
public partial class MyDerivedType : MyBaseType, ProtoBuf.IExtensible

[ProtoBuf.ProtoContract(Name=@"MyMessageProto")]                                                                  
public partial class MyMessage : ProtoBuf.IExtensible                                           
{                                                                                               
    [ProtoBuf.ProtoMember(1, IsRequired = false, Name = @"MyList", DataFormat = ProtoBuf.DataFormat.Default)]
    [System.ComponentModel.DefaultValue(null)]                                                  
    public List<MyDerivedType> MyList;  

Should do it (untested, not by a suitable computer). The key addition is the [ProtoInclude] on the base-type. I removed [Serializable] because protobuf-net really doesn't care about that.