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