Enum ToString with user friendly strings

后端 未结 23 2076
伪装坚强ぢ
伪装坚强ぢ 2020-11-22 11:44

My enum consists of the following values:

private enum PublishStatusses{
    NotCompleted,
    Completed,
    Error
};

I want to be able to

23条回答
  •  抹茶落季
    2020-11-22 12:25

    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)

提交回复
热议问题