tags:

views:

48

answers:

3

This may seem a little upside down faced, but what I want to be able to do is get an enum value from an enum by it's Description attribute.

So, if I have an enum declared as follows:

enum Testing
{
    [Description("David Gouge")]
    Dave = 1,
    [Description("Peter Gouge")]
    Pete = 2,
    [Description("Marie Gouge")]
    Ree = 3
}

I'd like to be able to get 2 back by supplying the string "Peter Gouge".

As a starting point, I can iterate through the enum fields and grab the field with the correct attribute:

string descriptionToMatch = "Peter Gouge";

        FieldInfo[] fields = typeof(Testing).GetFields();

        foreach (FieldInfo field in fields)
        {
            if (field.GetCustomAttributes(typeof(DescriptionAttribute), false).Count() > 0)
            {
                if (((DescriptionAttribute)field.GetCustomAttributes(typeof(DescriptionAttribute), false)[0]).Description == descriptionToMatch)
                {

                }
            }
        }

But then I'm stuck as to what to do in that inner if. Also not sure if this is the way to go in the first place.

Look forward to your help.

A: 

Ok, after typing all that I think this is a case of a decision right at the beginning leading me down the wrong path. Enum seemed the right way to go to start with, but a simple Dictionary<string, int> will suffice and be a hell of a lot easier to work with!

DavidGouge
+3  A: 

Using the extension method described here :

Testing t = Enum.GetValues(typeof(Testing))
                .Cast<Testing>()
                .Where(v => v.GetDescription() == descriptionToMatch)
                .FirstOrDefault();

If no matching value is found, it will return (Testing)0 (you might want to define a None member in your enum for this value)

Thomas Levesque
Ahh, LINQ to the rescue once again. I really like this solution, thanks!
DavidGouge
+1  A: 
return field.GetRawConstantValue();

You could of course cast it back to Testing if required.

Ani
Excellent, thank you.
DavidGouge
It looks promising, but it doesn't work. I get an `InvalidOperationException` : "Operation is not valid due to the current state of the object."
Thomas Levesque
Just had a look in Reflector: the only class that actually implements this method is `MdFieldInfo`. In `RtFieldInfo`, it just throws an InvalidOperationException.
Thomas Levesque
It works fine; you have to skip the first result in the enumeration.typeof(Testing).GetFields[1].GetRawConstantValue();Alternatively, you could filter on type MdFieldInfo as suggested by Thomas. This is probably a better solution.
Ani
Indeed... the first field is `value__`, and it's not actually an enum member
Thomas Levesque