Helpful Enum Description Attribute

Filed under .NET, VB Feng Shui

imageWhen 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

  1. Rich says:

    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

  2. Admin says:

    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

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*