ProtoBuf.net – Handling optional primitives
If you are dealing with protos containing optional primitives, it’s not immediately obvious how you’d deal with them in C#.
For example, if the proto contains an optional int and you generated the C# class, the results would as follows:
optional int32 bar_ukey = 13;
>protogen -i:BarTest.proto -o:BarTestProto.cs
private int _bar_ukey =default(int);
[ProtoBuf.ProtoMember(13, IsRequired = false, Name=@"bar_ukey", DataFormat = ProtoBuf.DataFormat.TwosComplement)][System.ComponentModel.DefaultValue(default(int))]
public int bar_ukey
{
get { return _bar_ukey; }
set { _bar_ukey = value; }
}
As you can see, the highlighted default value doesn’t take the optional nature of the field into account.
To fix this, protogen needs to be run with detectMissing argument as follows:
protogen -i:BarTest.proto -o:BarTestProto.cs -p:detectMissing
which results in the property getting generated as
private int? _bar_ukey;
[ProtoBuf.ProtoMember(13, IsRequired = false, Name=@"bar_ukey", DataFormat = ProtoBuf.DataFormat.TwosComplement)]
public int bar_ukey
{
get { return _bar_ukey?? default(int); }
set { _bar_ukey = value; }
}
[System.Xml.Serialization.XmlIgnore]
[System.ComponentModel.Browsable(false)]
public bool bar_ukeySpecified
{
get { return _bar_ukey != null; }
set { if (value == (_bar_ukey== null)) _bar_ukey = value ? bar_ukey : (int?)null; }
}
private bool ShouldSerializebar_ukey() { return bar_ukeySpecified; }
private void Resetbar_ukey() { bar_ukeySpecified = false; }
Side note: Also tucked away in the -p template property observable and preObservable options for the observable pattern.