I have a client generated enum class with values already defined. I have to populate a dropdown list with all the enum values with a different order than the order they are declared in.
First, I thought its as simple as just rearranging the order they are declared in to the order I need and the method Enum.GetValues would return them in the new order. However, it still returns them in order of the enum value.
public enum SampleEnum
{
Item1 = 0,
Item2 = 1,
Item3 = 2,
Item4 = 3
}
var enumValues = Enum.GetValues(typeof(SampleEnum)).Cast<SampleEnum>();
foreach (var item in enumValues)
{
Console.WriteLine(item.ToString());
}
Console.ReadLine();
Then I rearrange the order like this but the result is the same.
public enum SampleEnum
{
Item2 = 1,
Item3 = 2,
Item1 = 0,
Item4 = 3
}
To solve this, I add a custom attribute called EnumOrder and then create a helper method that will return the enum values in this custom order.
[AttributeUsage(AttributeTargets.Field)]
public class EnumOrderAttribute : Attribute
{
public readonly int Order;
public EnumOrderAttribute(int order)
{
Order = order;
}
}
public static class Enums
{
public static IEnumerable<T> ToList<T>() where T : IConvertible
{
var type = typeof(T);
if (!type.IsEnum)
throw new System.ArgumentException($"{type.Name} is not an Enum.");
var values = Enum.GetValues(type).Cast<T>().ToList();
return values.OrderBy(x => {
var memInfo = type.GetMember(type.GetEnumName(x));
var orderAttributes = memInfo[0].GetCustomAttributes(typeof(EnumOrderAttribute), false);
var order = orderAttributes.Length > 0
? ((EnumOrderAttribute)orderAttributes.First()).Order
: Convert.ToInt32(x) + values.Count;
return order;
});
}
}
Then I use the attribute on my enum as below
public enum SampleEnum
{
[EnumOrder(0)]
Item2 = 1,
[EnumOrder(1)]
Item3 = 2,
Item1 = 0,
Item4 = 3
}