My enum consists of the following values:
private enum PublishStatusses{
NotCompleted,
Completed,
Error
};
I want to be able to
I happen to be a VB.NET fan, so here's my version, combining the DescriptionAttribute method with an extension method. First, the results:
Imports System.ComponentModel ' For
Module Module1
'''
''' An Enum type with three values and descriptions
'''
Public Enum EnumType
V1 = 1
' This one has no description
V2 = 2
V3 = 3
End Enum
Sub Main()
' Description method is an extension in EnumExtensions
For Each v As EnumType In [Enum].GetValues(GetType(EnumType))
Console.WriteLine("Enum {0} has value {1} and description {2}",
v,
CInt(v),
v.Description
)
Next
' Output:
' Enum V1 has value 1 and description One
' Enum V2 has value 2 and description V2
' Enum V3 has value 3 and description Three
End Sub
End Module
Basic stuff: an enum called EnumType with three values V1, V2 and V3. The "magic" happens in the Console.WriteLine call in Sub Main(), where the last argument is simply v.Description
. This returns "One" for V1, "V2" for V2, and "Three" for V3. This Description-method is in fact an extension method, defined in another module called EnumExtensions:
Option Strict On
Option Explicit On
Option Infer Off
Imports System.Runtime.CompilerServices
Imports System.Reflection
Imports System.ComponentModel
Module EnumExtensions
Private _Descriptions As New Dictionary(Of String, String)
'''
''' This extension method adds a Description method
''' to all enum members. The result of the method is the
''' value of the Description attribute if present, else
''' the normal ToString() representation of the enum value.
'''
Public Function Description(e As [Enum]) As String
' Get the type of the enum
Dim enumType As Type = e.GetType()
' Get the name of the enum value
Dim name As String = e.ToString()
' Construct a full name for this enum value
Dim fullName As String = enumType.FullName + "." + name
' See if we have looked it up earlier
Dim enumDescription As String = Nothing
If _Descriptions.TryGetValue(fullName, enumDescription) Then
' Yes we have - return previous value
Return enumDescription
End If
' Find the value of the Description attribute on this enum value
Dim members As MemberInfo() = enumType.GetMember(name)
If members IsNot Nothing AndAlso members.Length > 0 Then
Dim descriptions() As Object = members(0).GetCustomAttributes(GetType(DescriptionAttribute), False)
If descriptions IsNot Nothing AndAlso descriptions.Length > 0 Then
' Set name to description found
name = DirectCast(descriptions(0), DescriptionAttribute).Description
End If
End If
' Save the name in the dictionary:
_Descriptions.Add(fullName, name)
' Return the name
Return name
End Function
End Module
Because looking up description attributes using Reflection
is slow, the lookups are also cached in a private Dictionary
, that is populated on demand.
(Sorry for the VB.NET solution - it should be relatively straighforward to translate it to C#, and my C# is rusty on new subjects like extensions)