2

proto2 構文の proto ファイルがあります。protogen を使用して C# ファイルを自動生成しようとしています。エラーなしでファイルを生成できますが、プロジェクトのビルド中にエラーが発生します (C# ファイルは Visual Studio の .Net 5 プロジェクトの一部です)。エラーは次のようになります。

エラー 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」の両方のメソッドの静的クラスで発生します。追加の Google パッケージなしで protobuf-net パッケージのみを使用することはできませんか? そうでない場合、どのパッケージを追加の依存関係として追加する必要がありますか? 些細なことを見逃しているかもしれませんが、今のところ理解できないようです。

4

1 に答える 1

3

ここでは Google の参照は必要ありません。これは、フィールドに関連する記述子メタ データ型です。protobuf-net の protobuf-net.Reflection パッケージには、まさにこれが期待できる場所に実装されています。FieldOptionsGoogle.Protobuf.Reflection.FieldOptions

でも!これがあなたの期待どおりになるとは思えません。このシナリオでは、「カスタム オプション」を定義しました。カスタム オプションはランタイム インスタンス データとは関係ありません。これらは .proto DSL の一部であり、通常はコード生成に影響を与えるために使用されます。あなたの場合、それは次のようになります:

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

(またはそのようなもの)

ここでのポイントは、( ) はスキーマ フィールド"ExtensionTypeName"について話す場合にのみ適用されるということです。これが、(スキーマ フィールド定義のインスタンスを表す)からぶら下がっている理由です。実行時の使用とは何の関係もありません。さらに、protobuf-netは現在、生成された C# にカスタム オプションをパッケージ化していません(おそらく、属性内の base-64 チャンクとしてパッケージ化することができますが、現在はパッケージ化しません)。FieldOptionsTestMessage

では、これを一歩引いてみましょう。拡張機能はあなたにとって何sampleValue を意味し、どのような場合に関連していると思いますか?

于 2021-02-16T16:37:37.360 に答える