When you work with Enums, often, it’s nice to have a description to go along with the value. Of course, you can use reflection to retrieve the name of the enum, and that’s sufficient for many purposes. But sometimes, using the name ends up being awkward, or just won’t work.
For those times, I created an EnumDisplayName Attribute.
First, the attribute definition:
<AttributeUsage(AttributeTargets.Field)> _ Public Class EnumDisplayNameAttribute Inherits Attribute Public Property DisplayName As String Public Sub New(ByVal DisplayName As String) Me.DisplayName = DisplayName End Sub End Class
Using it would then look something like this:
Public Class Core Public Enum ChimeSoundsEnum <EnumDisplayName("None")> _ None = 0 <EnumDisplayName("Air Raid")> _ AirRaid = 1 <EnumDisplayName("Beeper")> _ Beeper = 2
Now, all you need is an extension method on Enum to read the DisplayName for a particular enum value:
Imports System.Runtime.CompilerServices <Extension()> _ Public Function DisplayName(ByVal e As [Enum]) As String Dim enumType = e.GetType If enumType.IsEnum Then Dim f = enumType.GetField(e.ToString()) Dim displayNameAttribute = DirectCast(f.GetCustomAttributes(GetType(EnumDisplayNameAttribute), False).FirstOrDefault(), EnumDisplayNameAttribute) If displayNameAttribute IsNot Nothing Then Return displayNameAttribute.DisplayName End If End If Return [Enum].GetName(enumType, e) End Function
And finally, to read all the DisplayNames for a particular Enum type:
Public Function GetEnumDisplayNames(ByVal et As Type) As String() If et.IsEnum Then Dim l = New List(Of String) Dim flds = From f In et.GetFields Where f.IsLiteral = True For Each f In flds Dim desc = DirectCast(f.GetValue(f), [Enum]).DisplayName() If Desc IsNot Nothing Then l.Add(desc) End If Next Return l.ToArray Else Return Nothing End If End Function
Using that last function, you get back an array of DisplayNames that you can then databind to (for, say the ItemSource of a ListBox).
And finally, using these same techniques, you can create any number of other Enum metadata elements to make enums much more useful and easier to work with. You could have a ShortName attribute, a DataColumn attribute, maybe a PermissionLevel attribute, etc.
2 Comments
Another way to attack this is to use the “built in” Description attribute. It works the same way, but you don’t have to declare your own attribute type.
http://msdn.microsoft.com/en-us/library/system.componentmodel.descriptionattribute.aspx
You know, if it was a snake….
Doh. and I even knew about that Description attribute, I just had always used it in conjunction with Properties and methods for objects and controls that might show up in a property browser window. Never occurred to me to use it with Enums like that.
Very cool!
Thanks