获取通用枚举的描述属性

时间:2016-04-12 12:23:32

标签: c# generics enums attributes

我在尝试使用枚举的通用方面遇到了一些困难。我读过它并不那么简单,我似乎无法找到解决方案。

我正在尝试创建一个泛型函数,对于枚举类型,它将返回每个枚举值的描述​​。我想保持它的通用性,而不是为每个枚举类型复制这个方法...

这是我到目前为止所拥有的:

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'

3 个答案:

答案 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();
}