Как установить значение для свойства <string, string> карты protobuf в C # - PullRequest
3 голосов
/ 11 марта 2019

У меня есть следующее сообщение protoc3:

message LocalizedString {
  map<string, string> translations = 1
}

При компиляции в C # я получаю следующий автоматически сгенерированный код:

using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace PKIo {

  /// <summary>Holder for reflection information generated from io/common/localization.proto</summary>
  public static partial class LocalizationReflection {

    #region Descriptor
    /// <summary>File descriptor for io/common/localization.proto</summary>
    public static pbr::FileDescriptor Descriptor {
      get { return descriptor; }
    }
    private static pbr::FileDescriptor descriptor;

    static LocalizationReflection() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          string.Concat(
            "Chxpby9jb21tb24vbG9jYWxpemF0aW9uLnByb3RvEgJpbyKDAQoPTG9jYWxp",
            "emVkU3RyaW5nEjsKDHRyYW5zbGF0aW9ucxgBIAMoCzIlLmlvLkxvY2FsaXpl",
            "ZFN0cmluZy5UcmFuc2xhdGlvbnNFbnRyeRozChFUcmFuc2xhdGlvbnNFbnRy",
            "eRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBQi1aJHN0YXNoLnBh",
            "c3NraXQuY29tL2lvL21vZGVsL3Nkay9nby9pb6oCBFBLSW9iBnByb3RvMw=="));
      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
          new pbr::FileDescriptor[] { },
          new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
            new pbr::GeneratedClrTypeInfo(typeof(global::PKIo.LocalizedString), global::PKIo.LocalizedString.Parser, new[]{ "Translations" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, })
          }));
    }
    #endregion

  }
  #region Messages
  /// <summary>
  /// Localized strings are optionally used to provide translated values for each of supported language.
  /// </summary>
  public sealed partial class LocalizedString : pb::IMessage<LocalizedString> {
    private static readonly pb::MessageParser<LocalizedString> _parser = new pb::MessageParser<LocalizedString>(() => new LocalizedString());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<LocalizedString> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::PKIo.LocalizationReflection.Descriptor.MessageTypes[0]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public LocalizedString() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public LocalizedString(LocalizedString other) : this() {
      translations_ = other.translations_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public LocalizedString Clone() {
      return new LocalizedString(this);
    }

    /// <summary>Field number for the "translations" field.</summary>
    public const int TranslationsFieldNumber = 1;
    private static readonly pbc::MapField<string, string>.Codec _map_translations_codec
        = new pbc::MapField<string, string>.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForString(18), 10);
    private readonly pbc::MapField<string, string> translations_ = new pbc::MapField<string, string>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::MapField<string, string> Translations {
      get { return translations_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as LocalizedString);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(LocalizedString other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (!Translations.Equals(other.Translations)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      hash ^= Translations.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      translations_.WriteTo(output, _map_translations_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      size += translations_.CalculateSize(_map_translations_codec);
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(LocalizedString other) {
      if (other == null) {
        return;
      }
      translations_.Add(other.translations_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            translations_.AddEntriesFrom(input, _map_translations_codec);
            break;
          }
        }
      }
    }

  }

  #endregion

}

У меня есть другое сообщение со свойством LocalizedString, которое я использую в качестве входных данных для функции rpc, но я не могу понять, как установить свойства для Translations. В сгенерированном коде Translations помечен как доступный только для чтения.

Как создать объект сообщения protobuf, содержащий карту, подобную этой, в C #?

Ответы [ 2 ]

1 голос
/ 11 марта 2019

Итак, после изучения документации я обнаружил, что Google.Protobuf.Collections.MapField< TKey, TValue > имеет геттеры и сеттеры.

Значения могут передаваться либо ключу, паре значений, либо словарю в метод Add карты.

var localizedName = new LocalizedString();

localizedName.Translations.Add(new Dictionary<string, string>(){
  {"ES","Hola"},
  {"FR","Bonjour"},
  {"JA","こんにちは"},
  {"TH","สวัสดี"},
});

localizedName.Translations.Add("ZH_HANS", "你好");

Чтобы получить значение, существует метод TryGetValue:

var translation = "";
localizedName.Translations.TryGetValue("TH", out translation);
// translation == "สวัสดี"
0 голосов
/ 11 марта 2019

В методе MergeFrom он дает возможность добавлять значения в translations в строке translations_.Add(other.translations_);:

[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(LocalizedString other) {
      if (other == null) {
        return;
      }
      translations_.Add(other.translations_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

Ответить " Как создать объект сообщения protobufкоторая содержит такую ​​карту в C #", см.:

https://developers.google.com/protocol-buffers/docs/reference/csharp-generated

https://developers.google.com/protocol-buffers/docs/reference/csharp/class/google/protobuf/collections/map-field-t-key-t-value-

Также в github есть запрос на получение, который обеспечивает" Поддержка карт Proto3 для C #", чтобы понять, как это реализовано:

https://github.com/protocolbuffers/protobuf/pull/543

Также обратитесь к ним, чтобы проверить, помогает ли это:

Словарь в буферах протокола

Как работает поддержка Protobuf-net для Dictionary / KeyValuePair?

...