protobuf-net 缺少可选字段的 has_ 函数?

Posted

技术标签:

【中文标题】protobuf-net 缺少可选字段的 has_ 函数?【英文标题】:protobuf-net missing has_ function for optional fields?. 【发布时间】:2013-09-19 08:02:55 【问题描述】:

我们使用协议缓冲区在本机 C++ 应用程序之间进行通信,而且还通过 protobuf-net r666 在本机 C++ 应用程序和 .NET 应用程序(都是 VS2012)之间进行通信。 我们在 C++ 中严重依赖可用于可选元素的 has_ 函数。

例如如果我们有一个带有可选 bool 字段的消息,可能是未设置,设置为 true,或者设置为 false。

在 C++ 中,这可以使用函数 has_field 进行检查,如果设置,则可以使用 get_field 函数获取内容。如果未设置,则调用 get_field,则 get 返回默认值,如果未显式设置则为 false(对于布尔值)。

这在 C++ 中完美运行,但是,在 protobuf-net 中,我们似乎找不到等效的 has_ 函数,并且,当收到消息时,该字段被添加到消息中,并且它的内容设置为默认,为假。字段有默认也不是灾难,但问题是没有has_函数来检查消息中是否设置了。

请告知这是否是一个错误,或者我们是否错过了 protobuf-net 中的某些内容并且这实际上是可能的

提前谢谢。 维姆

【问题讨论】:

在 protobuf-net 问题 406 中回复。线程在那里继续。 【参考方案1】:

(我知道我们已经在 issue tracker 中介绍了这个 - 这纯粹是为了可见性等)

这与从 .proto 文件生成类有关,在 protobuf-net 的情况下是通过 protogen 工具生成的。默认情况下,它不会创建与has_* 等效的方法,但是可以使用-p:detectMissing 开关启用它——这会导致它创建*Specified 访问器。这里的命名是一个 .NET 习惯用法,*Specified 被其他一些 .NET 序列化程序和内部代码识别。它还生成一个私有的ShouldSerialize* 方法,这又有助于一些内部.NET 代码。

在这种特定情况下,名为value 的成员存在次要问题,导致混淆; csharp.xslt 文件现已更新以解决此问题。


更新:在完全托管重写中,使用proto2 语法(默认)时默认生成ShouldSerialize*() 方法。不需要额外的参数。 *Specified 成员没有被添加(它与 ShouldSerialize*() 相比没有其他用途。

注意,当使用proto3时,序列化规则的变化意味着这个概念不再有意义。一个值被序列化当且仅当它不是默认值时,它总是 null/false/zero/empty。没有“默认值但指定”的概念。因此,ShouldSerialize*() 方法通常不再有用,并且不会生成。我愿意为proto3 选择生成它们,它们基本上意味着“非默认”,如果这有助于一些真正的编码场景。

【讨论】:

以上是关于protobuf-net 缺少可选字段的 has_ 函数?的主要内容,如果未能解决你的问题,请参考以下文章

使用protobuf-net继承时如何选择字段号?

编译 protobuf-net 生成的代码时出错

protobuf-net 保留未来字段

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

protobuf-net 和重复字段

protobuf-net 生成的 .proto 文件中的字段命名约定不正确?