我们使用协议缓冲区在本机C ++应用程序之间进行通信,但也使用protobuf-net r666在本机C ++应用程序和.NET应用程序(都是VS2012)之间进行通信。 我们在可选元素的has_函数上严重依赖C ++。
E.g。如果我们有一个带有字段可选bool的消息,则可以是它未设置,设置为true或设置为false。
在C ++中,这可以使用函数has_field进行检查,如果已设置,则可以使用get_field函数获取内容。如果没有设置,并且调用了get_field,则get返回默认值,如果没有显式设置,则返回false(对于布尔值)。
这在C ++中完美地运行,但是,在protobuf-net中,我们似乎无法找到has_函数的等价物,并且,当收到消息时,该字段被添加到消息中并且其内容被设置为默认值为false。具有默认值的字段不是灾难,但问题是没有has_函数来检查它是否在消息中设置。
请告知这是否是一个错误,或者我们是否错过了protobuf-net中的内容并且这实际上是可能的
提前谢谢。 维姆答案 0 :(得分:5)
(我知道我们已经在issue tracker中介绍了这一点 - 这纯粹是为了提高知名度等)
这涉及从.proto文件生成类,在protobuf-net的情况下通过protogen工具生成类。默认情况下,它不会创建等效的has_*
方法,但可以使用-p:detectMissing
开关启用此选项 - 这会使其创建*Specified
个访问者。这里的命名是.NET习惯用法,其他.NET序列化程序和内部代码都可以识别*Specified
。它还生成一个私有的ShouldSerialize*
方法,它再次帮助一些内部.NET代码。
在这个特定情况下,有一个名为value
的成员导致混淆的次要问题; csharp.xslt
文件现已更新,以解释此问题。
更新:在完全托管的重写中,使用ShouldSerialize*()
语法(默认值)时默认生成proto2
方法。无需其他参数。 *Specified
成员未添加(在ShouldSerialize*()
上没有其他用途。
请注意,使用proto3
时,对序列化规则的更改意味着此概念不再具有意义。当且仅当值不是默认值时才会序列化值,该值始终为null / false / zero / empty。没有“默认值但指定”的概念。因此,ShouldSerialize*()
方法通常不再有用,并且不生成。我愿意为proto3
选择性地生成它们,它们基本上意味着“非默认”,如果这有助于一些真正的编码方案。