我目前正在基于this suggestion实现字符串和枚举的关联。就是这样,我有一个Description
属性与每个枚举元素相关联。在该页面上还有一个函数,它根据给定的枚举返回描述的字符串。我现在要实现的是反向函数,也就是说,给定一个输入字符串查找带有相应描述的枚举(如果存在),否则返回null。
我尝试了(T) Enum.Parse(typeof(T), "teststring")
,但它会抛出异常。
答案 0 :(得分:14)
你必须编写自己的反向方法。库存Parse()方法显然不了解您的描述属性。
这样的事情应该有效:
public static T GetEnumValueFromDescription<T>(string description)
{
MemberInfo[] fis = typeof(T).GetFields();
foreach (var fi in fis)
{
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0 && attributes[0].Description == description)
return (T)Enum.Parse(typeof(T), fi.Name);
}
throw new Exception("Not found");
}
但是,如果找不到枚举值,你会想要找到一个更好的事情而不是抛出异常。 :)
答案 1 :(得分:2)
static string GetEnumDescription<T>(T value) {
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute),
false
);
if (attributes != null &&
attributes.Length > 0) {
return attributes[0].Description;
}
else {
return value.ToString();
}
}
static T ParseDescriptionToEnum<T>(string description) {
Array array = Enum.GetValues(typeof(T));
var list = new List<T>(array.Length);
for(int i = 0; i < array.Length; i++) {
list.Add((T)array.GetValue(i));
}
var dict = list.Select(v => new {
Value = v,
Description = GetEnumDescription(v) }
)
.ToDictionary(x => x.Description, x => x.Value);
return dict[description];
}
我没有尝试过错误检查。请注意,不需要在每次调用方法时创建字典,但我太懒了,无法修复它。
用法:
enum SomeEnum {
[Description("First Value")]
FirstValue,
SecondValue
}
SomeEnum value = ParseDescriptionToEnum<SomeEnum>("First Value");
通过的测试:
[Fact]
public void Can_parse_a_value_with_a_description_to_an_enum() {
string description = "First Value";
SomeEnum value = ParseDescriptionToEnum<SomeEnum>(description);
Assert.Equal(SomeEnum.FirstValue, value);
}
[Fact]
public void Can_parse_a_value_without_a_description_to_an_enum() {
string description = "SecondValue";
SomeEnum value = ParseDescriptionToEnum<SomeEnum>(description);
Assert.Equal(SomeEnum.SecondValue, value);
}
答案 2 :(得分:1)
我会赞成安娜的回答,但我没有这样做的声誉。部分基于她的答案,这是我提出的双向解决方案。向ParseEnum方法提供defaultValue可以涵盖相同Enum根据其使用情况可能具有不同默认值的情况。
public static string GetDescription<T>(this object enumerationValue) where T : struct
{
// throw an exception if enumerationValue is not an Enum
Type type = enumerationValue.GetType();
if (!type.IsEnum)
{
throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
}
//Tries to find a DescriptionAttribute for a potential friendly name for the enum
MemberInfo[] memberInfo = type.GetMember(enumerationValue.ToString());
if (memberInfo != null && memberInfo.Length > 0)
{
DescriptionAttribute[] attributes = (DescriptionAttribute[])memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
{
//Pull out the description value
return attributes[0].Description;
}
}
//In case we have no description attribute, we'll just return the ToString of the enum
return enumerationValue.ToString();
}
public static T ParseEnum<T>(this string stringValue, T defaultValue)
{
// throw an exception if T is not an Enum
Type type = typeof(T);
if (!type.IsEnum)
{
throw new ArgumentException("T must be of Enum type", "T");
}
//Tries to find a DescriptionAttribute for a potential friendly name for the enum
MemberInfo[] fields = type.GetFields();
foreach (var field in fields)
{
DescriptionAttribute[] attributes = (DescriptionAttribute[])field.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0 && attributes[0].Description == stringValue)
{
return (T)Enum.Parse(typeof(T), field.Name);
}
}
//In case we couldn't find a matching description attribute, we'll just return the defaultValue that we provided
return defaultValue;
}
答案 3 :(得分:1)
您也可以使用Humanizer。要获得您所写的描述:
EAssemblyUnit.eUCAL1.Humanize();
并从描述中获取枚举,这是你想要的,你可以写:
"UCAL1".DehumanizeTo<EAssemblyUnit>();
免责声明:我是Humanizer的创作者。
答案 4 :(得分:0)
This answer相关问题显示了如何检索给定类型的属性。您可以使用类似的方法将给定字符串与Enum
的描述属性进行比较。