Как использовать расширения protobuf-net? - PullRequest
4 голосов
/ 08 февраля 2010

Я создал файл .proto, а ProtoBufTool успешно создал файл .cs. Я новичок в csharp и пытаюсь установить поля расширения. Но не уверен, как это сделать? У кого-нибудь есть примеры использования расширений с использованием protobuf-net.

Мой файл .proto:

package messages;
message DMsg 
{
    optional int32 msgtype = 1;
    extensions 100 to max;
}
extend DMsg
{
optional string fltColumns = 101;
}

Вот класс, который был создан:

//------------------------------------------------------------------------------
// 
//     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.IExtensible.GetExtensionObject(bool createIfMissing)
    { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
}

}

1 Ответ

6 голосов
/ 08 февраля 2010

protobuf-net не поддерживает блестящий для расширений; вам нужно использовать номера полей (я не думаю, что это что-то делает с fltColumns на данный момент). Однако, чтобы получить значения из , вы должны использовать Extensible.GetValue<T> / TryGetValue<T> (обратите внимание на себя: создайте эти методы расширения в C # 3.0). Чтобы установить значение, используйте AppendValue<T> - он не может знать, является ли это одиночным значением или списком (repeated), поэтому один и тот же API обрабатывает оба сценария.

Возможно, версия Джона (намного ближе к версии Java) имеет лучшую поддержку здесь.

Пример (я использую рукописные классы для краткости, но он должен работать и с сгенерированными типами):

    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; }
    }
...