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”。
此解决方案假设两件事。
Kaltura 生成的 API(不应修改)作为源存在于您的项目中
与您的 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);
你的EntryStatus
class只有静态成员,而且它不能被自己之外的任何人实例化(所以没关系)。
新的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" 段落之后的代码块不包含 StringEnum
或 EntryStatus
。我真的听不懂你在说什么
最后一点,您可能希望在 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));
}
正在尝试检索 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”。
此解决方案假设两件事。
Kaltura 生成的 API(不应修改)作为源存在于您的项目中
与您的
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);
你的EntryStatus
class只有静态成员,而且它不能被自己之外的任何人实例化(所以没关系)。
新的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" 段落之后的代码块不包含 StringEnum
或 EntryStatus
。我真的听不懂你在说什么
最后一点,您可能希望在 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));
}