Get a List<string> of my enum attributes with a generic method
c#, custom-attributes, enums, generics
Solution
Let's try to keep this more general purpose.
I have an extension method that could grab attributes off of enum values. This would give you quick access to the attributes.
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();
}
}
Using this, you could create some queries to get what you want.
var valuesOfLevels =
Enum.GetValues(typeof(E_Levels)).Cast<E_Levels>()
.Select(level => level.GetAttribute<ValueOfEnumAttribute>().Value);
So your `GetValuesOf()` method (which is not a great name for such a specialty method IMHO) can be written like this:
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();
}
Now you may call the method like so:
var levelValues = GetValueOf<E_Levels>();
// levelValues = { "Low level", "Normal level", "High level" }
Problem
At start, we have this basic enum. ``` public enum E_Levels { [ValueOfEnum("Low level")] LOW, [ValueOfEnum("Normal level")] NORMAL, [ValueOfEnum("High level")] HIGH } ``` And I would like to get a `List<string>` whatever the enum. Something like `Extensions.GetValuesOfEnum<E_Levels>()` which could return a `List<string>` with "Low level", "Normal level" and "High level" in it. StackOF helped me to get one value attribute : ``` 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; } } ``` And I can call this method whatever the enum : `E_Levels.LOW.ToValueOfEnum()`. Furthermore, StackOF helped me to get a `List<string>` for a specific enum. I made this method in a controller : ``` 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; } ``` But this way requires me to rewrite the same method for each enum. So I tried to add this generic method my class 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; } } ``` But in my foreach, `.ToValueOfEnum()` is an unknown method. So I am in trouble, I hoped I could find a way to not rewrite again and again the same method for each enum...