我有一个表示系统中所有材料汇编代码的枚举:
public enum EAssemblyUnit
{
[Description("UCAL1")]
eUCAL1,
[Description("UCAL1-3CP")]
eUCAL13CP,
[Description("UCAL40-3CP")]
eUCAL403CP, // ...
}
在系统另一部分的遗留代码中,我的对象标记了与枚举描述匹配的字符串。鉴于其中一个字符串,获得枚举值的最简洁方法是什么?我想象的是:
public EAssemblyUnit FromDescription(string AU)
{
EAssemblyUnit eAU = <value we find with description matching AU>
return eAU;
}
答案 0 :(得分:8)
你需要遍历枚举的所有静态字段(这就是它们存储在反射中的方式),找到每个静态字段的描述属性......当你发现正确的属性时,获取字段的值
例如:
public static T GetValue<T>(string description)
{
foreach (var field in typeof(T).GetFields())
{
var descriptions = (DescriptionAttribute[])
field.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (descriptions.Any(x => x.Description == description))
{
return (T) field.GetValue(null);
}
}
throw new SomeException("Description not found");
}
(这是通用的,只是为了让它可以重用于不同的枚举。)
显然,如果你经常这样做,你会想要缓存描述,例如:
public static class DescriptionDictionary<T> where T : struct
{
private static readonly Dictionary<string, T> Map =
new Dictionary<string, T>();
static DescriptionDictionary()
{
if (typeof(T).BaseType != typeof(Enum))
{
throw new ArgumentException("Must only use with enums");
}
// Could do this with a LINQ query, admittedly...
foreach (var field in typeof(T).GetFields
(BindingFlags.Public | BindingFlags.Static))
{
T value = (T) field.GetValue(null);
foreach (var description in (DescriptionAttribute[])
field.GetCustomAttributes(typeof(DescriptionAttribute), false))
{
// TODO: Decide what to do if a description comes up
// more than once
Map[description.Description] = value;
}
}
}
public static T GetValue(string description)
{
T ret;
if (Map.TryGetValue(description, out ret))
{
return ret;
}
throw new WhateverException("Description not found");
}
}
答案 1 :(得分:0)
public EAssemblyUnit FromDescription(string AU)
{
EAssemblyUnit eAU = Enum.Parse(typeof(EAssemblyUnit), AU, true);
return eAU;
}
答案 2 :(得分:0)
您也可以使用Humanizer。要获得描述,您可以使用:
EAssemblyUnit.eUCAL1.Humanize();
并从描述中获取枚举,您可以使用
"UCAL1".DehumanizeTo<EAssemblyUnit>();
免责声明:我是Humanizer的创作者。