Kaltura API C# 如何获取 StringEnum 的值

Kaltura API C# How to get Value of StringEnum

正在尝试检索 EntryStatus 的值(class 进一步向下),即(“READY”、“DELETED”、“ERROR_IMPORTING”),其方式类似于下面的

EntryStatus test = EntryStatus.DELETED;
Console.WriteLine(test);
EntryStatus value = test;
string val = value.ToString();//see note1
Console.WriteLine(val);

以上代码的结果为:

3
3

我想要 Console.WriteLine 到 return 的第二个“DELETED” 我不明白如何检索枚举的字母部分。

note1: 将此行更改为 int val = (int)value; 给出无法将 EntryStatus 转换为 int 的错误。这个枚举似乎不像其他 C# 枚举。

EntryStatus 是 StringEnum 的子 class。

编辑:EntryStatus 是 Kaltura 生成的一部分 API,不应修改。

public sealed class EntryStatus : StringEnum
{
    public static readonly EntryStatus ERROR_IMPORTING = new EntryStatus("-2");
    public static readonly EntryStatus ERROR_CONVERTING = new EntryStatus("-1");
    public static readonly EntryStatus IMPORT = new EntryStatus("0");
    public static readonly EntryStatus INFECTED = new EntryStatus("virusScan.Infected");
    public static readonly EntryStatus SCAN_FAILURE = new EntryStatus("virusScan.ScanFailure");
    public static readonly EntryStatus PRECONVERT = new EntryStatus("1");
    public static readonly EntryStatus READY = new EntryStatus("2");
    public static readonly EntryStatus DELETED = new EntryStatus("3");
    public static readonly EntryStatus PENDING = new EntryStatus("4");
    public static readonly EntryStatus MODERATE = new EntryStatus("5");
    public static readonly EntryStatus BLOCKED = new EntryStatus("6");
    public static readonly EntryStatus NO_CONTENT = new EntryStatus("7");

    private EntryStatus(string name) : base(name) { }
}

底classStringEnum是:

编辑:StringEnum class 是 Kaltura 生成的一部分 API,不应更改

public class StringEnum
{
  private readonly string name;

  protected StringEnum(string name)
  {
    this.name = name;
  }

  public override string ToString()
  {
    return name;
  }

  public static StringEnum Parse(Type type, string name)
  {
    FieldInfo[] fields = type.GetFields();
    foreach (FieldInfo field in fields)
    {
      object val = field.GetValue(null);
      if (val.GetType().BaseType == typeof(StringEnum))
      {
        if (val.ToString() == name)
          return (StringEnum)val;
        }
      }
      return null;
    }
  }
}

请接受 System.Reflection、EntryStatus class 和 StringEnum class 作为问题的给定。只能使用关键字 partial 来修改 EntryStatus 和 StringEnum。我试图了解 Kaltura 生成的 API 库,它们是其中的一部分。非常感谢您的所有帮助。

--更新--

这是重写问题后的更新。

我不太清楚你要找的东西应该叫什么。现在,我使用“OtherName”。

此解决方案假设两件事。

  1. Kaltura 生成的 API(不应修改)作为源存在于您的项目中

  2. 与您的 EntryStatus 事物关联的名称是唯一的(或大部分是唯一的)。

可能的解决方案:

在您的项目中创建一个名为 EntryStatus.partial.cs 的新文件。添加以下代码:

public sealed partial class EntryStatus
{
    private Dictionary<string, string> _namesDictionary = null;

    public string AsOtherName()
    {
        if (_namesDictionary == null)
        {
            var fields = this.GetType().GetFields(BindingFlags.Public | BindingFlags.Static);
            _namesDictionary = new Dictionary<string, string>(fields.Length);
            foreach (var field in fields)
            {
                var fieldValue = field.GetValue(null);
                var fieldName = (fieldValue as EntryStatus).ToString();
                _namesDictionary[fieldName] = field.Name;
            }
        }

        return _namesDictionary[ToString()];
    }
}

这会修改 EntryStatus 定义,但不会触及现有代码。如果这种关系过于亲密,您需要构建一个反映 EntryStatus class 的 class 并构建该字典。

全部完成后,EntryStatus.ERROR_CONVERTING.AsOtherName() returns "ERROR_CONVERTING".

话又说回来,输入 EntryStatus.ERROR_CONVERTING 和一大堆代码只是想出 "ERROR_CONVERTING"

有什么意义

---旧答案---

我不太确定您要做什么,但这可能会有所帮助:

首先,我将您的 Parse 函数更改为通用函数,并包含一个 TryParse 方法(相信我,您会喜欢的)。您当前的 Parse returns null 失败。大多数用户的期望是 Parse 方法在失败时抛出异常。

下面的代码完成了我认为您正在描述的内容,但我很确定它不会执行您想要的。请参阅下面我建议的更改,了解我认为您想要的内容。

最大的变化是我把你的FieldInfo[] fields = type.GetFields();改成了var fields = type.GetFields(BindingFlags.Public|BindingFlags.Static);你的EntryStatusclass只有静态成员,而且它不能被自己之外的任何人实例化(所以没关系)。

新的Parse(和TryParse)代码:

public static bool TryParse<T>(string name, out StringEnum stringEnum) where T : StringEnum
{
    stringEnum = null;
    var type = typeof(T);
    var fields = type.GetFields(BindingFlags.Public|BindingFlags.Static);
    foreach (var field in fields)
    {
        var val = field.GetValue(null);
        if (val is StringEnum typedVal)
        {
            if (typedVal.ToString() == name)
            {
                stringEnum = typedVal;
                return true;
            }
        }
    }
    return false;
}

public static StringEnum Parse<T>(string name) where T: StringEnum
{
    if (StringEnum.TryParse<T>(name, out var val))
    {
        return val;
    }
    else
    {
        return null;        //you should probably make this throw
    }
}

有了这个,如果我这样说:

Debug.WriteLine(StringEnum.Parse<EntryStatus>("virusScan.Infected"));

我明白了

virusScan.Infected

所以...

我认为你想要的是改变:

if (typedVal.ToString() == name)    //in my TryParse method

if (field.Name == name)

现在,如果你 运行 StringEnum.Parse<EntryStatus>("SCAN_FAILURE") 你会得到:

virusScan.ScanFailure

这与您所说的相近吗?如果你想要一个更好的答案,你需要删除大部分以开头的段落开头的内容“我称之为API”并将其替换为文本和代码组成一个Minimal Reproduceable Example。例如 "I call the API" 段落之后的代码块不包含 StringEnumEntryStatus。我真的听不懂你在说什么

最后一点,您可能希望在 StringEnum class 中包含一个 隐式运算符 以允许隐式转换为字符串。如果您不想隐式转换,您至少应该提供一个 显式运算符 以允许 casting 到字符串。参见:User-defined Implicit and Explicit Conversion Operators

我想你想为 KalturaEntryStatus 和其他类似的枚举建模。在我看来,这里的反思有点矫枉过正。所以我提出了另一种解决方案,它基于@Flydog57 也建议的简单 Dictionary<string, string>
该示例仅包含两个枚举,只有 2 个成员:

/// <summary>
/// Contains the various return codes of Kaltura API functions.
/// </summary>
public class KalturaEnum
{
    /// <summary>
    /// Contains the return codes for function XXX.
    /// </summary>
    public static readonly KalturaEnum KalturaEntryStatus = new KalturaEnum(nameof(KalturaEntryStatus),
        ("-2", "Error importing"),
        ("-1", "Error converting")
        );

    /// <summary>
    /// Contains the return codes for function YYY.
    /// </summary>
    public static readonly KalturaEnum KalturaBatchJobType = new KalturaEnum(nameof(KalturaBatchJobType),
        ("ReachInternal.ReachInternalQueueHandler", "Reach internal queue handler"),
        ("0", "Convert")
        );

    private readonly Dictionary<string, string> values;

    private KalturaEnum(string enumName, params (string Code, string Description)[] values)
    {
        if (string.IsNullOrWhiteSpace(enumName))
            throw new ArgumentException($"'{nameof(enumName)}' cannot be null or whitespace.", nameof(enumName));
        EnumName = enumName;
        this.values = values.ToDictionary(a => a.Code, a => a.Description, StringComparer.OrdinalIgnoreCase);
    }

    /// <summary>
    /// Gets the name of this enumeration (not really usefull...).
    /// </summary>
    public string EnumName { get; }

    /// <summary>
    /// Gets the description of a return code by using a case-insensitive search.
    /// </summary>
    /// <param name="code">The return code of a API function.</param>
    /// <returns>The description for <paramref name="code"/> or "Unknown return value '<paramref name="code"/>' for the type <see cref="EnumName"/>."</returns>
    public string GetDescription(string code) => code != null && values.TryGetValue(code, out var name) ? name : $"Unknown return value '{code ?? "null"}' for the type {EnumName}.";
}

测试并输出:

Console.WriteLine(KalturaEnum.KalturaEntryStatus.GetDescription("-2"));
Console.WriteLine(KalturaEnum.KalturaBatchJobType.GetDescription("1"));
Error importing  
Unknown return value '1' for the type KalturaBatchJobType.

在你的代码中它看起来像这样:

foreach (MediaEntry MediaEntry in result.Objects)
{
    Console.WriteLine(KalturaEnum.KalturaEntryStatus.GetDescription(MediaEntry.Status)); 
}