簡體   English   中英

如何從 C# 中的 Protobuf 讀取 EnumValueOptions?

[英]How to read EnumValueOptions from Protobuf in C#?

我想讀取“EnumValueOptions”類型的字段。 我發現的所有示例都與“C#”以外的語言有關。

有一個協議:

syntax = "proto3";   
import "google/protobuf/descriptor.proto"; 

extend google.protobuf.EnumValueOptions {
   string enum_name = 51234;
};;

message Options {
  enum Profiles{
        A = 0 [(enum_name) = "AAA"];
        B = 1 [(enum_name) = "BBB"]; 
        C = 2 [(enum_name) = "CCC"];
  };
  Profiles profile = 1;
}

如何在代碼 C# 中讀取“enum_name”?

期待:

foreach(Profiles profile in Enum.GetValues(typeof(Profiles)))
{
    string name = ????; //name in ("AAA","BBB","CCC")
}

Protobuf 不會為枚舉值選項生成 c# 代碼,因此如果您想檢索這些值,您需要在src/google/protobuf/compiler/csharp/csharp_doc_comment.cc編輯源代碼。

這是一個例子

void WriteEnumValueDocComment(io::Printer* printer, const EnumValueDescriptor* value) 
{
    WriteDocCommentBody(printer, value);
    
    // Example code to prepend c# attribute like '[Custom(name: value)]' before a enum field
    const Message& options = value->options();
    const Reflection* reflection = options.GetReflection();
    std::vector<const FieldDescriptor*> fields;
    reflection->ListFields(options, &fields);
    for (int i = 0; i < fields.size(); i++)
    {
        std::string name = fields[i]->full_name();
        std::string fieldval;
        TextFormat::PrintFieldValueToString(options, fields[i], -1, &fieldval);
        printer->Print("[Custom($name$: $value$)]", "name", name, "value", fieldval);
    }
}

重新生成 cs 文件,然后您可以使用GetCustomAttribute方法來檢索這些信息。

原型:

syntax = "proto2";

package my.protos;
option csharp_namespace = "My.Protos";

import "google/protobuf/descriptor.proto"; // For enum extension.

extend google.protobuf.EnumValueOptions {
    optional string NameDisplay = 50001;
    optional string NameAbbrev  = 50002;
}

enum MyOperation {
    MY_CREATE = 0 [(NameDisplay) = "create"];
    MY_DELETE = 1 [(NameDisplay) = "delete"];
    MY_READ   = 2 [(NameDisplay) = "read"];
}

C# 中的用法:

Google.Protobuf.Reflection.EnumDescriptor descriptor = 
    MyProtosReflection.Descriptor.FindTypeByName<Google.Protobuf.Reflection.EnumDescriptor>(
        typeof(MyOperation).Name
    );

Google.Protobuf.Reflection.EnumValueDescriptor valueDescriptor =
    descriptor.FindValueByNumber((int)MyOperation.Create);

string nameDisplay = valueDescriptor.GetOption(MyProtosExtensions.NameDisplay);

我正在用 C# 編程 - 這個 protobuf 的東西還是很新的

如果您有以下擴展 EnumValueOptions 的 proto 文件:

extend google.protobuf.EnumValueOptions {
  string Value = 101;
  bool AutoEnrol = 102;
}

Protobuf 將通過自動生成生成EnumValueOptionsExtensions類。 要訪問它,請使用 EnumValueOptionsExtensions.Value 或 EnumValueOptionsExtensions.AutoEnrol,根據稍后/下面的 C# 代碼示例。

然后在同一個或另一個 proto 文件中,使用以下內容創建一個枚舉:

enum SystemRoleType {
  ReservedRole = 0 [(Value) = "SystemRoleType.ReservedRole", (AutoEnrol) = false];
  Administrator = 1001 [(Value) = "SystemRoleType.Administrator", (AutoEnrol) = false];
  Editor = 1002 [(Value) = "SystemRoleType.Editor", (AutoEnrol) = false];
  ContentCreator = 1003 [(Value) = "SystemRoleType.ContentCreator", (AutoEnrol) = false];
  User = 1004 [(Value) = "SystemRoleType.ContentCreator", (AutoEnrol) = true];
}

同樣,這將通過 protobuf 自動生成生成SystemRoleTypeReflection類。

然后在 C# 中,相應地包含您的命名空間(也包括:Google.Protobuf.Reflection),然后您可以在 C# 中執行以下操作

EnumDescriptor SystemRoleTypeTypeEnumDescriptor = SystemRoleTypeReflection.Descriptor.FindTypeByName<EnumDescriptor>(typeof(SystemRoleType).Name);
foreach (SystemRoleType system_role_type in Enum.GetValues(typeof(SystemRoleType)))
{
    EnumValueDescriptor enum_value_descriptor = SystemRoleTypeTypeEnumDescriptor.FindValueByNumber((int)system_role_type);
    var selector_value = enum_value_descriptor.GetOptions().GetExtension<string>(EnumValueOptionsExtensions.Value);
    var auto_enrolment = enum_value_descriptor.GetOptions().GetExtension<bool>(EnumValueOptionsExtensions.AutoEnrol);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM