Your reference to this question had me very confused, and very curious about all these features of C# enums I had never seen. But then I realized that the reason that code won't compile as C# is because it's Java.
–
Carl GOct 7 '12 at 13:31

I suspect there is a significant performance hit for using reflection as described in this solution. The code for Will's method of using the ToFriendlyString extension method is much easier to understand, and its performance should be extremely fast too.
–
humbadsApr 9 '14 at 18:52

I like the version that @RayL linked as it will only add the extension method to Enums. If that's all you want to use this for (as indicated with the ArgumentException, then there's no reason to have the method be completely generic.
–
krillgarAug 4 '14 at 12:32

It does mean that every enum needs it's own extension method. This is more general use and does require more work, but you'd probably want to quantify what "fast" means before we decide on the performance.
–
Ray BooysenMar 30 at 16:07

yes, thanks for the input though. I put some remarks in noldorim's post regarding this solution.
–
Boris CallensJan 26 '09 at 11:36

3

This is so much cleaner than the Attribute answer. Nice!
–
pennyraveMay 6 '12 at 18:27

1

@pennyrave: Eh. Lots of UI components are expecting to find and use DisplayNameAttribute and DescriptionAttribute. In fact, now, I use these and an extension method to easily get those values out.
–
WillMay 6 '12 at 18:30

9

The issue I see with this is that you're constantly writing these extension methods. With the attribute mechanism, it's a simple way of decorating it and only ever calling one method.
–
Ray BooysenJan 7 '14 at 17:50

Although valid, I like the attribute way more. That way I can put my toSTring method in a seperate library, whilst putting the custom string representation with the enum itself
–
Boris CallensJan 26 '09 at 11:13

1

Fair enough. I suppose one advantage of this method is that you can include an argument with the method specifying some state variable, and then change what string representation is returned depending on this.
–
NoldorinJan 26 '09 at 11:24

1

Yes, it all depends on the scope of the method I guess. While the Attribute way is more generic, your solution is more localized.. It's all about needs in the end.
–
Boris CallensJan 26 '09 at 11:34

1

You can put extension methods anywhere you want. You just have to reference it where you want to use them.
–
WillJan 26 '09 at 12:07

Yes, but this would mean that this one extention method should be rewritten every time you introduce a new enum you want to have a friendly name for. This would also mean that ALL your applications would carry around friendly names for ALL your other applications...
–
Boris CallensJan 26 '09 at 14:40

edit: for user-friendly strings, you need to go through a .resource to get internationalisation/localisation done, and it would arguably be better to use a fixed key based on the enum key than a decorator attribute on the same.

I returns the literal value of the enum, not some user friendly one.
–
Boris CallensJan 26 '09 at 11:34

2

oic - well there's a pretty big case that you have to go through a string resource library based on this value then, because the alternative (decorator attribs) won't support I18N
–
annakataJan 26 '09 at 11:38

In case of I18N I would make the GetDescription() method search in the resource lib for a translated string and fall back to the description and then fall back to the literal.
–
Boris CallensJan 26 '09 at 14:44

+1 for MyEnum.ToString() as the resource key for localization. i've been doing that for years
–
jackvsworldJun 18 '13 at 7:12

@annakata we've actually extended the attribute mechanism to include support for l18N, it's a simple change in fact.
–
Ray BooysenJan 7 '14 at 17:51

toString is not safe in all cases - an enum with multiple entries with the same value (say for integer enums) will return the key of the first matching value, not the key of the item tested, this is why Enum.GetName is preferred
–
annakataJan 26 '09 at 11:20

2

Well it was the easiest solution for his specific enum
–
LemmyJan 26 '09 at 11:38

I'm sorry, but thanks for trying to be helpful! Though because this is a Q&A site, answers should be an attempt to directly answer the question. And the question specifically states "I don't need to be able to go from string to value again." Once again, thanks!
–
JesseApr 18 '13 at 0:31

4

Thanks for the positive criticism. It's always difficult being new to a site and learning about its culture and nuances. I am glad there are people like you who set the new guys straight. Once again, thanks for not dumping on the new guy.
–
bjrichardsonMay 6 '13 at 20:49

1

Hey you're welcome; we were all there once. =)
–
JesseMay 6 '13 at 20:51

The omission of a check for multiple Description attributes is on purpose. If the enum has two, and you're using to to generate a description, I'd like to think that is an exceptional circumstance. I think the actual bug is I don't do a Single() to have an exception thrown. Otherwise the whole method signature makes no sense. GetDescription()? Which description? An aggregate?
–
Ray BooysenApr 14 '11 at 10:43

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)
''' <summary>
''' 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.
''' </summary>
<Extension>
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)

It's a mystery as to why this comment isn't the accepted one, or most upvoted - no reflection, no unnecessary attributes, ideal for simple situations where the enum is already nicely named. You could take this answer a step further and allow for adding spaces in-between capital letters before returning, 'My Enum'.
–
VixJul 14 at 8:25