Of course, you can use the DisplayAttribute
to annotate your Enum
s.
enum OrderStatus
{
[Display(Description="Long Desc", Name="Awaiting Authorization", ShortName="Wait Auth")]
AwaitingAuthorization,
[Display(Description="...", Name="...", ShortName="...")]
InProduction,
[Display(Description="...", Name="...", ShortName="...")]
AwaitingDespatch
}
You can also opt to create an extension method taking any enumeration value and returning its display name based on the attribute set to it to tidy up the displayed values in the UI, as follows:
public static class EnumExtensions
{
public static string ToName(this Enum enumValue)
{
var displayAttribute = enumValue.GetType()
.GetMember(enumValue.ToString())[0]
.GetCustomAttributes(false)
.Select(a => a as DisplayAttribute)
.FirstOrDefault();
return displayAttribute?.Name ?? enumValue.ToString();
}
}
With
public enum Test
{
[Display(Name="AAA")]
a,
b
}
Code:
Console.WriteLine(Test.a.ToName());
Console.WriteLine(Test.b.ToName());
Results
AAA
b
I want to bind my enums to a SelectList with an extension method:
For type safety, I wouldn't use an extension methods, but instead a static class that deals with the Enum type:
Pre C# 7.3 version. Since Enum
is not a valid type constraint prior to 7.3 (and it would cause a compile-time exception), you'll end up by considering that enums are value types and they implement some interfaces, in order to restrict the type parameter as close to Enum
as possible.
public static class Enums<TEnum> where TEnum : struct, IComparable, IFormattable, IConvertible
{
static Enums()
{
if (!typeof(TEnum).IsEnum)
{
throw new InvalidOperationException();
}
}
}
C# 7.3+ version, with compile time checking... yay!
public static class Enums<TEnum> where TEnum : Enum
{
}
GetValues Method for the class:
public static IEnumerable<TEnum> GetValues(bool includeFirst)
{
var result = ((TEnum[])Enum.GetValues(typeof(TEnum))).ToList();
if (!includeZero)
result = result.Where(r => r != default).ToList();
return result;
}
If you follow Enum Guidelines and include the Default (zero) value, we can ignore it (sometimes we want to display the value like "None Selected" and sometimes we don't "Invalid Selection").
Then we can add another method:
public static IEnumerable<string> GetNames(bool includeFirst)
{
var result = GetValue(includeFirst)
.Select(v => v.ToName())
.ToList();
return result;
}