How to use protobuf-net extensions?
I have created a .proto file and the ProtoBufTool successfully created .cs file. I am kinda new to csharp and I am trying to set the extension fields. But not sure how to do it? Does anybody have any examples how to use extensions using protobuf-net.
My .proto file:
package messages;
message DMsg
{
optional int32 msgtype = 1;
extensions 100 to max;
}
extend DMsg
{
optional string fltColumns = 101;
}
Here is the class that got created:
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------
// Generated from: message.proto
namespace messages
{
[global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"DMsg")]
public partial class DMsg : global::ProtoBuf.IExtensible
{
public DMsg() {}
private int _msgtype = default(int);
[global::ProtoBuf.ProtoMember(1, IsRequired = false, Name=@"msgtype", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)][global::System.ComponentModel.DefaultValue(default(int))]
public int msgtype
{
get { return _msgtype; }
set { _msgtype = value; }
}
private global::ProtoBuf.IExtension extensionObject;
global::ProtoBuf.IExtension global::ProtoBuf.IExtens开发者_StackOverflow中文版ible.GetExtensionObject(bool createIfMissing)
{ return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
}
}
protobuf-net doesn't have brilliant support for extensions; you need to use the field numbers (I don't think it does anything with fltColumns
at the moment). However, to get values out you should be able to use Extensible.GetValue<T>
/ TryGetValue<T>
(note to self: make those extension methods in C# 3.0). To set a value use AppendValue<T>
- it can't know whether this is a single-value or a list (repeated
), so the same API handles both scenarios.
It is possible that Jon's version (being much closer to the Java version) has better support here.
Example (I'm using hand-written classes for brevity, but it should work with generated types too):
static void Main()
{
MyData data = new MyData();
data.Id = 123;
// something we know only by field id...
Extensible.AppendValue<string>(data, 27, "my name");
string myName = Extensible.GetValue<string>(data, 27);
// this should be OK too (i.e. if we loaded it into something that
// *did* understand that 27 means Name)
MyKnownData known = Serializer.ChangeType<MyData, MyKnownData>(data);
Console.WriteLine(known.Id);
Console.WriteLine(known.Name);
}
[ProtoContract]
class MyData : Extensible
{
[ProtoMember(1)]
public int Id { get; set; }
}
[ProtoContract]
class MyKnownData
{
[ProtoMember(1)]
public int Id { get; set; }
[ProtoMember(27)]
public string Name{ get; set; }
}
精彩评论