You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Protobuf-net检索.proto中的自定义扩展选项

protobuf-net读取.proto自定义字段选项的实现方法

protobuf-net默认生成的C#类是轻量序列化专用版本,不会内嵌.proto的完整元数据描述符,这是你找不到FieldOptions实例的根本原因——它和Google.Protobuf默认生成带静态Descriptor的逻辑不同,默认不会把完整.proto编译产物打进程序集。

操作流程

  • 生成代码时开启描述符输出
    调用protogen生成C#类时追加--descriptor参数,工具会自动把对应.proto编译得到的FileDescriptor二进制作为内嵌资源打包进程序集,同时在生成类中补充描述符访问相关的代码。你之前生成的代码里没有Descriptor静态属性,就是因为没开启这个配置。
  • 通过描述符链路获取目标字段的FieldOptions
    重新生成代码后,消息类会新增静态Descriptor属性(类型为Google.Protobuf.Reflection.MessageDescriptor),按字段编号/字段名拿到对应FieldDescriptor后,访问它的CustomOptions属性就能拿到对应的FieldOptions实例。
  • 调用生成的扩展方法读取选项值
    拿到FieldOptions实例后,直接调用protogen自动生成的GetACustomOption()扩展方法,就能取到.proto里定义的选项值。

代码示例

重新生成代码后,读取逻辑如下:

using ProtoGenTest.GeneratedClasses;
using Google.Protobuf.Reflection;

// 获取MyMessage的消息描述符
MessageDescriptor myMsgDescriptor = MyMessage.Descriptor;
// 定位Id字段的描述符
FieldDescriptor idFieldDesc = myMsgDescriptor.FindFieldByNumber(12345); 
// 取出字段的自定义选项对象
FieldOptions options = idFieldDesc.CustomOptions;
// 调用生成的扩展方法读取自定义选项值
int customOptValue = options.GetACustomOption();
// 最终得到的值就是proto中配置的5

补充说明

  • 如果你不想重新生成代码,也可以手动加载提前编译好的.desc描述符文件,通过FileDescriptor.BuildFromByteStrings()手动构建描述符集,再按上述链路读取选项。但这种方式维护成本高,很容易出现序列化类和描述符版本不匹配的问题,生产环境不推荐使用。
  • protogen默认生成的GetACustomOption/SetACustomOption扩展方法,是protobuf-net对Google.Protobuf选项类型做的适配,方便你用protobuf-net的扩展API操作选项对象,但前提是你得先拿到对应选项实例——这些实例只能从完整的描述符链路获取,默认生成的轻量序列化类本身不携带这部分元数据。

内容的提问来源于stack exchange,提问作者Nougat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 22:18:13