新闻详情

新闻详情

首页 / 资讯中心 / 详情

protobuf C 如何启用实验性 proto2 支持并使用 HasXYZ/ClearXYZ 与 extension API

发布时间:2026/9/12 1:43:41来源:尧图网络
protobuf C 如何启用实验性 proto2 支持并使用 HasXYZ/ClearXYZ 与 extension API
protobuf C# 如何启用实验性 proto2 支持并使用 HasXYZ/ClearXYZ 与 extension API【免费下载链接】protobufProtocol Buffers - Googles data interchange format项目地址: https://gitcode.com/GitHub_Trending/pr/protobuf如果你的 C# 项目需要与遗留系统交换 proto2 格式的数据required/optional字段、字段 presence、扩展字段就需要在 Google.Protobuf 中启用 proto2 支持。自 Google.Protobuf 3.10 版本起proto2 支持以实验性experimental方式发布它不破坏现有 proto3 用法但 proto2 相关生成代码和公共 API 可能随反馈新增、删除或调整源码中IExtendableMessageT接口也明确标注 experimental and is subject to change见 IExtendableMessage.cs。本文按 docs/csharp/proto2.md 与 csharp/README.md 说明如何生成并使用这部分 API。准备条件安装 NuGet 包与 protoc按照 csharp/README.md 的说明C# 运行时最简使用方式是通过 NuGet 包Google.Protobuf运行时库。其目标框架为 .NET 4.5net45、.NET Standard 1.1 和 2.0netstandard1.1/netstandard2.0、.NET 5net50不支持 .NET 3.5。Google.Protobuf.Tools包含预编译的protoc.exe以及包内tools目录下的 well known.proto文件副本。生成 C# 代码时对.proto文件调用protoc并加上--csharp_out选项。另外用旧编译器C# 7.2 之前编译生成代码时需要在项目中定义GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE符号使生成类不实现使用ref struct类型的IBufferMessage接口。启用 proto2在 .proto 文件中声明 syntaxproto2 特性只在带syntax proto2;声明的 proto2 文件中生效与其他语言的用法一致。文档同时强调 proto3 仍是推荐版本proto2 支持面向遗留系统互操作legacy system interop和高级用途。对这样的文件运行protoc --csharp_out后生成代码会额外包含字段 presence 和扩展相关的成员。使用 HasXYZ/ClearXYZ 处理 optional/required 字段proto2 中的 message 与 proto3 类似提供普通的属性读写同时为字段 presence 增加了属性和方法对optional/required字段XYZ生成代码包含用于检查 presence 的HasXYZ属性和用于清除值的ClearXYZ方法来源docs/csharp/proto2.md。文档中的 proto 示例message Foo { optional Bar bar 1; required Baz baz 2; }对应的文档示例代码示例结果展示 presence 行为var foo new Foo(); Assert.IsNull(foo.Bar); Assert.False(foo.HasBar); foo.Bar new Bar(); Assert.True(foo.HasBar); foo.ClearBar();即未赋值时HasBar为 false赋值后为 trueClearBar()清除后可回到未设置状态。使用 extension APIIExtendableMessage 与生成的扩展容器定义了 extension range 的 message 会实现IExtendableMessageT接口提供以下方法完整定义见 IExtendableMessage.csGetExtensionTValue(ExtensionT, TValue)读取单值扩展扩展不存在时返回默认值。GetExtensionTValue(RepeatedExtensionT, TValue)读取 repeated 扩展未设置时返回null以避免不必要的分配。GetOrInitializeExtensionTValue(RepeatedExtensionT, TValue)读取 repeated 扩展并初始化不会返回null。SetExtensionTValue(ExtensionT, TValue, TValue)设置扩展值。HasExtensionTValue(ExtensionT, TValue)判断扩展是否已设置。ClearExtension单值与 repeated 两个重载从消息中移除扩展。扩展会生成为静态容器方便取用。文档示例文件foo.proto中定义在文件作用域的扩展会生成FooExtensions类嵌套在 message 内的extend则会生成嵌套的Extensions类。可以用using static把所有扩展带入作用域option csharp_namespace FooBar; extend Foo { optional Baz foo_ext 124; } message Baz { extend Foo { repeated Baz repeated_foo_ext 125; } }生成的 C# 结构/* initialization */为文档中省略的初始化代码public static partial class FooExtensions { public static readonly ExtensionFoo, Baz FooExt /* initialization */; } public partial class Baz { public partial static class Extensions { public static readonly RepeatedExtensionFoo, Baz RepeatedFooExt /* initialization */; } }使用示例using static FooBar.FooExtensions; using static FooBar.Baz.Extensions; var foo new Foo(); foo.SetExtension(FooExt, new Baz()); foo.GetOrInitializeExtension(RepeatedFooExt).Add(new Baz());解析带扩展的消息ExtensionRegistry从输入流解析消息时扩展不会自动生效需要构造ExtensionRegistry并交给解析器。文档示例其中HasExtension的断言用于验证注册与否的差异var registry new ExtensionRegistry() { Baz.Extensions.FooExt }; var foo Foo.Factory.WithExtensionRegistry(registry).ParseFrom(input); Assert.True(foo.HasExtension(Baz.Extensions.FooExt)); var fooNoRegistry Foo.Factory.ParseFrom(input); Assert.False(fooNoRegistry.HasExtension(Baz.Extensions.FooExt));WithExtensionRegistry返回一个新的、配置了该注册表的解析器见 MessageParser.cs 中的MessageParser.WithExtensionRegistry与MessageParserT.WithExtensionRegistry。上面的示例同时给出了验证方式注册了 registry 的解析结果HasExtension为 true未注册的为 false。如果不想手工罗列扩展可以用文档中扩展后的反射 API 动态构建注册表var extensions Baz.Descriptor.Extensions.GetExtensionsInDeclarationOrder(Foo.Descriptor); var registry new ExtensionRegistry(); registry.AddRange(extensions.Select(f f.Extension)); var baz Foo.Descriptor.Parser.WithExtensionRegistry(registry).ParseFrom(input); foreach (var field in extensions) { if (field.Accessor.HasValue(baz)) { Console.WriteLine(${field.Name}: {field.Accessor.GetValue(baz)}); } }配套的新增反射成员包括FieldDescriptor.Extension取扩展字段背后的扩展标识符可加入ExtensionRegistry、FieldDescriptor.IsExtension、FieldDescriptor.ExtendeeType、IFieldAccessor.HasValue判断字段值是否已设置对 proto3 字段会抛InvalidOperationException、FileDescriptor.Syntax、FileDescriptor.Extensions和MessageDescriptor.Extensions。required 字段与 IsInitialized 检查proto2 消息中存在 required 字段时初始化指 required 字段包括子消息中的是否全部已设置。这个实现中解析器和输入流不会自行检查消息的初始化状态或抛错——处理缺失 required 字段的方式由你自行决定。文档给出的检查方法是MessageExtensions中的IsInitialized扩展方法见 MessageExtensions.cs在解析后手动调用即可判断消息是否完整。迁移限制与注意事项proto2 生成代码与公共 API 是实验性的后续版本可能新增、删除或调整迁移时不要假定当前 API 形状长期稳定。原CustomOptionsAPI 已被弃用。文档建议改用新生成的扩展标识符通过GetOptionAPI 安全地访问自定义选项repeated 字段和 message 等可克隆值会深拷贝。反射访问扩展时注意IFieldAccessor.HasValue仅适用于 proto2 字段对 proto3 字段会抛InvalidOperationException。完成上述步骤后可验证的结果是生成的 proto2 消息类具备HasXYZ/ClearXYZ成员using static引入的扩展可通过SetExtension/GetExtension读写且只有经过WithExtensionRegistry配置的解析器才能把线上扩展解析进消息以HasExtension的返回值为判断依据。【免费下载链接】protobufProtocol Buffers - Googles data interchange format项目地址: https://gitcode.com/GitHub_Trending/pr/protobuf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

论文初稿查AI率完全没必要花钱:2026写作、调研、检测工具搭配直接抄 2026/9/12 2:28:47

论文初稿查AI率完全没必要花钱:2026写作、调研、检测工具搭配直接抄

又到开题和赶稿季,后台被问爆的问题永远是那几个:“用DeepSeek写的论文能查出来吗?”“哪个AIGC检测免费又准?”“ChatGPT写完怎么降AI率?” 这两年工具迭代太快,很多人手里用着大模型,却对检测…

阅读更多 →
AIRI 官方实时语音转写(ASR/STT)提供者配置指南:免 API Key 的流式转录实战 2026/9/12 2:28:47

AIRI 官方实时语音转写(ASR/STT)提供者配置指南:免 API Key 的流式转录实战

AIRI 官方实时语音转写(ASR/STT)提供者配置指南:免 API Key 的流式转录实战 【免费下载链接】airi 💖🧸 Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into o…

阅读更多 →
AI写文献综述最怕的根本不是AIGC检测:2026分阶段工具选型,参考文献真实可查 2026/9/12 2:28:47

AI写文献综述最怕的根本不是AIGC检测:2026分阶段工具选型,参考文献真实可查

又到开题和论文季,很多同学用 AI 写文献综述的经历都很相似:初稿看着像模像样,一查参考文献却发现“论文不存在”“作者年份对不上”“观点和原文不是一回事”。更麻烦的是,直接生成的文字往往模板感强、AI 味重,放到论…

阅读更多 →
AI写文献综述总在参考文献上翻车?四类工具按需求分工,真实可查的中文初稿这样生成 2026/9/12 2:28:47

AI写文献综述总在参考文献上翻车?四类工具按需求分工,真实可查的中文初稿这样生成

又到开题、中期和毕业论文季,很多同学用 AI 的方式都很直接:打开 ChatGPT、DeepSeek 或 Kimi,输入题目,等待一篇“像模像样”的文献综述。结果往往是:行文很顺,框架也像样,但参考文献一查&#…

阅读更多 →
oh-my-pi 语义压缩的 rewrite 工具契约:草稿提交、损失声明与审查回合机制 2026/9/12 2:28:47

oh-my-pi 语义压缩的 rewrite 工具契约:草稿提交、损失声明与审查回合机制

oh-my-pi 语义压缩的 rewrite 工具契约:草稿提交、损失声明与审查回合机制 【免费下载链接】oh-my-pi ⌥ Coding agent with the IDE wired in 项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi 导读 本文剖析 oh-my-pi(pi&#xff0…

阅读更多 →
百万级数据导出零OOM:流式查询与SXSSFWorkbook实战 2026/9/12 2:25:47

百万级数据导出零OOM:流式查询与SXSSFWorkbook实战

1. 一次线上导出 OOM:事故现场与根因分析打开服务端的异常日志,最让人心里一沉的就是这行:java.lang.OutOfMemoryError: Java heap space如果这行出现在导出功能里,那基本可以断定:大量数据被一股脑加载进了堆内存&…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞