protobuf-net:如何注释派生类型的属性?

Posted

技术标签:

【中文标题】protobuf-net:如何注释派生类型的属性?【英文标题】:protobuf-net : how to annotate properties of derived type? 【发布时间】:2016-09-30 00:19:42 【问题描述】:

对于最新版本的protobuf-netr640 文件夹),如何最好地注释作为派生类型的ProtoMember

[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;  

我尝试将DynamicType 属性添加到ProtoMember 属性,但无法识别。

我需要一个可以从xml defsproto types 生成类的解决方案。所以理想情况下,这将通过在属性定义上注释的属性来完成。

似乎可以使用protogen.exe 生成基于包含import 语句的消息类型定义(.proto 文件)的类:

package MyPackage;                                                          

import "MyDerivedTypeProto.proto";                                                          

message MyMessage                                                                          
    repeated MyDerivedType MyList = 1;                                                          
       

import 语句显然对生成的 C# 类(.cs 文件)没有影响,除了添加注释:

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

【问题讨论】:

【参考方案1】:
[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;  

应该这样做(未经测试,不是通过合适的计算机)。关键添加是基本类型上的[ProtoInclude]。我删除了[Serializable],因为 protobuf-net 真的不在乎。

【讨论】:

感谢 Marc,但是否可以以某种方式注释 .proto 文件以便 protogen.exe 自动生成 ProtoInclude 属性? @BaltoStar 不,没有语法;但是,您可以将子类属性放在单独的partial 代码文件中,这样您就不需要编辑生成的了

以上是关于protobuf-net:如何注释派生类型的属性?的主要内容,如果未能解决你的问题,请参考以下文章

使用 protobuf-net 反序列化具有某些字段的派生类型的对象

使用 ProtoBuf-net 反序列化派生类型(字典)未正确设置对象字段

protobuf-net 序列化为基类

protobuf-net 使用索引属性时如何避免崩溃

仅在 ProtoBuf-net 中序列化基类

Protobuf-net / NetCore2:反序列化忽略带注释的私有字段