使用泛型方法获取我的枚举属性的List <string>

spr*_*tus 5 c# generics enums custom-attributes

一开始,我们有这个基本的枚举.

public enum E_Levels {

    [ValueOfEnum("Low level")]
    LOW,

    [ValueOfEnum("Normal level")]
    NORMAL,

    [ValueOfEnum("High level")]
    HIGH
}
Run Code Online (Sandbox Code Playgroud)

而且我想得到List<string> 任何一个枚举.这样的东西Extensions.GetValuesOfEnum<E_Levels>()可以返回List<string>"低级别","正常级别"和"高级别".

StackOF帮助我获得了一个值属性:

public static class Extensions {

    public static string ToValueOfEnum(this Enum value) {

        FieldInfo fieldInfo = value.GetType().GetField(value.ToString());
        ValueOfEnum[] attribs = fieldInfo.GetCustomAttributes(typeof(ValueOfEnum), false) as ValueOfEnum[];
        return attribs.Length > 0 ? attribs[0].value : null;
    }
}
Run Code Online (Sandbox Code Playgroud)

无论枚举如何,我都可以调用这种方法:E_Levels.LOW.ToValueOfEnum().

此外,StackOF帮助我获得了List<string>一个特定的枚举.我在控制器中制作了这个方法:

private List<string> GetLevels() {

List<string> levelsToReturn = new List<string>();
var levels = Enum.GetValues(typeof(E_Levels)).Cast<E_Levels>();
foreach(E_Levels l in levels) 
    levelsToReturn.Add(l.ToValueOfEnum());

return levelsToReturn;
}
Run Code Online (Sandbox Code Playgroud)

但是这种方式要求我为每个枚举重写相同的方法.
所以我尝试添加这个泛型方法我的类Extensions:

public static class Extensions {

    public static string ToValueOfEnum(this Enum value) {...}

    public static List<string> GetValuesOf<T>() {

        List<string> levelsToReturn = new List<string>();
        var levels = Enum.GetValues(typeof(T)).Cast<T>();
        foreach(T l in levels) 
        levelsToReturn.Add(l.ToValueOfEnum());

        return levelsToReturn;
    }
}
Run Code Online (Sandbox Code Playgroud)

但在我的foreach中,.ToValueOfEnum()是一种未知的方法.

所以我遇到了麻烦,我希望我能找到一种方法,不会一次又一次地为每个枚举重写相同的方法......

Jef*_*ado 8

让我们试着保持这个更普遍的目的.

我有一个扩展方法,可以从枚举值中获取属性.这将使您可以快速访问属性.

public static class EnumExtensions
{
    public static TAttribute GetAttribute<TAttribute>(this Enum value)
        where TAttribute : Attribute
    {
        var type = value.GetType();
        var name = Enum.GetName(type, value);
        return type.GetField(name)
            .GetCustomAttributes(false)
            .OfType<TAttribute>()
            .SingleOrDefault();
    }
}
Run Code Online (Sandbox Code Playgroud)

使用此功能,您可以创建一些查询以获得所需内容.

var valuesOfLevels =
    Enum.GetValues(typeof(E_Levels)).Cast<E_Levels>()
        .Select(level => level.GetAttribute<ValueOfEnumAttribute>().Value);
Run Code Online (Sandbox Code Playgroud)

所以你的GetValuesOf()方法(对于这种专业方法恕我直言并不是一个好名字)可以写成这样:

public static List<string> GetValuesOf<TEnum>()
    where TEnum : struct // can't constrain to enums so closest thing
{
    return Enum.GetValues(typeof(TEnum)).Cast<Enum>()
               .Select(val => val.GetAttribute<ValueOfEnumAttribute>().Value)
               .ToList();
}
Run Code Online (Sandbox Code Playgroud)

现在您可以这样调用方法:

var levelValues = GetValueOf<E_Levels>();
// levelValues = { "Low level", "Normal level", "High level" }
Run Code Online (Sandbox Code Playgroud)