Можно ли сгенерировать файлы C# с помощью protobuf-net для файлов proto2 с расширением FieldOptions?

У меня есть прото-файл с синтаксисом proto2. Я пытаюсь автоматически создать файл C# с помощью protogen. Хотя я могу сгенерировать файл без ошибок, я получаю сообщение об ошибке при сборке проекта (файл C# является частью проекта .Net 5 в Visual Studio). Ошибка выглядит так:

ошибка CS0400: тип или имя пространства имен "Google" не может быть найдено в глобальном пространстве имен (вам не хватает ссылки на сборку?)

Я добавил «descriptor.proto» по правильному пути, но, похоже, это не повлияет на то, как protogen автоматически генерирует файл C#.

myproto.proto

      syntax = "proto2";

import "google/protobuf/descriptor.proto";

package test;

extend google.protobuf.FieldOptions {
  optional string sampleValue = 50004;
}

message TestMessage {
  required string id = 1;
  optional float value = 2;
  optional string sample_val = 3;
}

myproto.cs

      // <auto-generated>
//   This file was generated by a tool; you should avoid making direct changes.
//   Consider using 'partial classes' to extend these types
//   Input: myproto.proto
// </auto-generated>

#region Designer generated code
#pragma warning disable CS0612, CS0618, CS1591, CS3021, IDE0079, IDE1006, RCS1036, RCS1057, RCS1085, RCS1192
namespace Test
{

    [global::ProtoBuf.ProtoContract()]
    public partial class TestMessage : global::ProtoBuf.IExtensible
    {
        private global::ProtoBuf.IExtension __pbn__extensionData;
        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);

        [global::ProtoBuf.ProtoMember(1, Name = @"id", IsRequired = true)]
        public string Id { get; set; }

        [global::ProtoBuf.ProtoMember(2, Name = @"value")]
        public float Value
        {
            get => __pbn__Value.GetValueOrDefault();
            set => __pbn__Value = value;
        }
        public bool ShouldSerializeValue() => __pbn__Value != null;
        public void ResetValue() => __pbn__Value = null;
        private float? __pbn__Value;

        [global::ProtoBuf.ProtoMember(3, Name = @"sample_val")]
        [global::System.ComponentModel.DefaultValue("")]
        public string SampleVal
        {
            get => __pbn__SampleVal ?? "";
            set => __pbn__SampleVal = value;
        }
        public bool ShouldSerializeSampleVal() => __pbn__SampleVal != null;
        public void ResetSampleVal() => __pbn__SampleVal = null;
        private string __pbn__SampleVal;

    }

    public static partial class Extensions
    {
        public static string GetsampleValue(this global::Google.Protobuf.Reflection.FieldOptions obj)
            => obj == null ? default : global::ProtoBuf.Extensible.GetValue<string>(obj, 50004);

        public static void SetsampleValue(this global::Google.Protobuf.Reflection.FieldOptions obj, string value)
            => global::ProtoBuf.Extensible.AppendValue<string>(obj, 50004, value);

    }
}

#pragma warning restore CS0612, CS0618, CS1591, CS3021, IDE0079, IDE1006, RCS1036, RCS1057, RCS1085, RCS1192
#endregion

Ошибка возникает в статическом классе Extensions

для обоих методов в созданном myproto.cs. Разве нельзя использовать только пакет protobuf-net без дополнительных пакетов Google? Если нет, то какой пакет мне нужно добавить в качестве дополнительной зависимости? Я могу упустить что-то тривиальное, но сейчас я не могу понять.

1 ответ

Ссылка Google здесь не требуется; вы расширили - это тип метаданных дескриптора , относящийся к полям. В protobuf-net есть реализация этого в пакете protobuf-net.Reflection, именно там, где это могло ожидать: Google.Protobuf.Reflection.FieldOptions

.

Тем не мение! Я сомневаюсь, что это сделает то, что вы ожидаете. В этом сценарии вы определили «настраиваемый параметр». Пользовательские параметры не связаны с данными экземпляра среды выполнения - они являются частью .proto DSL и обычно используются для влияния на генерацию кода ; в вашем случае это будет примерно так:

        optional string sample_val = 3 [sampleValue= "ExtensionTypeName"];

(или что-то вроде того)

Дело в том, что значение ( "ExtensionTypeName"

) применяется только когда речь идет о поле схемы , поэтому оно свисает с FieldOptions(который представляет собой экземпляр определения поля схемы). Это не имеет ничего общего с вашим TestMessageиспользование во время выполнения. Далее: protobuf-net в настоящее время не упаковывает пользовательские параметры в сгенерированный C# (он мог бы делать это, предположительно, как блок base-64 в атрибуте или аналогичный - в настоящее время этого просто нет).

Итак: сделаем шаг назад: что делает ваше расширение sampleValue

означает для вас , и к каким случаям, по вашему мнению, это относится?
Другие вопросы по тегам