我在尝试使用枚举的通用方面遇到了一些困难。我读过它并不那么简单,我似乎无法找到解决方案。
我正在尝试创建一个泛型函数,对于枚举类型,它将返回每个枚举值的描述。我想保持它的通用性,而不是为每个枚举类型复制这个方法...
这是我到目前为止所拥有的:
public static KeyValuePair<string, List<KeyValueDataItem>> ConvertEnumWithDescription<T>()
where T : struct, IConvertible
{
if (!typeof(T).IsEnum)
{
throw new Exception("Type given T must be an Enum");
}
var enumType = typeof(T).ToString().Split('.').Last();
var itemsList = Enum.GetValues(typeof(T))
.Cast<T>()
.Select(x => new KeyValueDataItem
{
Key = Convert.ToInt32(x),
Value = GetEnumDescription(Convert.ToInt32(x))
})
.ToList();
var res = new KeyValuePair<string, List<KeyValueDataItem>>(enumType, itemsList);
return res;
}
public static string GetEnumDescription(Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
return attributes[0].Description;
return value.ToString();
}
我目前面临的问题是:
无法从'int'转换为'System.Enum'
当我试图调用函数GetEnumDescription
时。
如果我将其转换为T
:
Value = GetEnumDescription((T)(object)Convert.ToInt32(x));
这是我得到的错误:
无法从'T'转换为'System.Enum'
答案 0 :(得分:3)
在这里,试试这个:
public static KeyValuePair<string, List<KeyValueDataItem>> ConvertEnumWithDescription<T>() where T : struct, IConvertible
{
if (!typeof(T).IsEnum)
{
throw new Exception("Type given T must be an Enum");
}
var enumType = typeof(T).ToString().Split('.').Last();
var itemsList = Enum.GetValues(typeof(T))
.Cast<T>()
.Select(x => new KeyValueDataItem
{
Key = Convert.ToInt32(x),
Value = GetEnumDescription<T>(x.ToString())
})
.ToList();
var res = new KeyValuePair<string, List<KeyValueDataItem>>(
enumType, itemsList);
return res;
}
public static string GetEnumDescription<T>(string value)
{
Type type = typeof(T);
var name = Enum.GetNames(type).Where(f => f.Equals(value, StringComparison.CurrentCultureIgnoreCase)).Select(d => d).FirstOrDefault();
if (name == null)
{
return string.Empty;
}
var field = type.GetField(name);
var customAttribute = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
return customAttribute.Length > 0 ? ((DescriptionAttribute)customAttribute[0]).Description : name;
}
基于:http://www.extensionmethod.net/csharp/enum/getenumdescription
答案 1 :(得分:1)
我冒昧地修改了代码的某些部分,比如将返回类型更改为更多的C#标准API返回值。
您可以观看它here。
public static EnumDescription ConvertEnumWithDescription<T>() where T : struct, IConvertible
{
if (!typeof(T).IsEnum)
{
throw new ArgumentException("Type given T must be an Enum");
}
var enumType = typeof(T).Name;
var valueDescriptions = Enum.GetValues(typeof (T))
.Cast<Enum>()
.ToDictionary(Convert.ToInt32, GetEnumDescription);
return new EnumDescription
{
Type = enumType,
ValueDescriptions = valueDescriptions
};
}
public static string GetEnumDescription(Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
return attributes[0].Description;
return value.ToString();
}
public class EnumDescription
{
public string Type { get; set; }
public IDictionary<int, string> ValueDescriptions { get; set; }
}
答案 2 :(得分:0)
稍微修改您的代码以将Type传递给description方法并将参数作为字符串值传递。然后将其转换回适当的枚举类型并检查说明。
public static KeyValuePair<string, List<KeyValueDataItem>> ConvertEnumWithDescription<T>() where T : struct, IConvertible
{
if (!typeof(T).IsEnum)
{
throw new Exception("Type given T must be an Enum");
}
var enumType = typeof(T).ToString().Split('.').Last();
var type = typeof(T);
var itemsList = Enum.GetValues(typeof(T))
.Cast<T>()
.Select(x => new KeyValueDataItem
{
Key = Convert.ToInt32(x),
Value = GetEnumDescription<T>(Enum.GetName(typeof(T), x))
})
.ToList();
var res = new KeyValuePair<string, List<KeyValueDataItem>>(
enumType, itemsList);
return res;
}
public static string GetEnumDescription<T>(string enumValue)
{
var value = Enum.Parse(typeof(T), enumValue);
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
return attributes[0].Description;
return value.ToString();
}