1

I want to persist the currently selected value of a combo box and restore it at a later time. To manage the value in the combo box I have an enumerated type with description attributes. The description attribute becomes (one of) the combo box string values at runtime and the enumerated constant associated with it is used internally for programming purposes. I got this technique from the following Stack Overflow post:

c#:How to use enum for storing string constants?

That post contained a link in one of the comments to this blog post:

http://weblogs.asp.net/grantbarrington/archive/2009/01/19/enumhelper-getting-a-friendly-description-from-an-enum.aspx

The GetDescription() method that does the enum to string conversion magic is replicated here from that post, with the addition of the "this" keyword to the parameter list so I can use it as an extension method with enumerated types:

    public static string GetDescription(this Enum en)
    {
        Type type = en.GetType();

        MemberInfo[] memInfo = type.GetMember(en.ToString());

        if (memInfo != null && memInfo.Length > 0)
        {
            object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

            if (attrs != null && attrs.Length > 0)
            {
                return ((DescriptionAttribute)attrs[0]).Description;
            }
        }

        // Unable to find a description attribute for the enum.  Just return the
        //  value of the ToString() method.
        return en.ToString();
    }

So I have one side of the equation fully fleshed out and it works quite well. Now I want to go the other way. I want to create a method that takes a string and returns the correct enumerated value by walking the description attributes for a particular enumerated type, and returning the enumerated value associated with the description attribute that matches the string. A hypothetical method declaration would be:

public static Enum GetEnumValue(string str){}

However an immediate problem with that declaration is that it does not return a specific enum type. I am not sure how to declare and cast things properly so that the correct enumerated type is returned. Is it possible to create this complementary method to the GetDescription() method and if so, how do I craft it so it works conveniently for any particular enum type? If I can do this I'll have a convenient solution for the common problem of converting between the strings used to persist control settings and then restoring them later, all supported by enums.

Community
  • 1
  • 1
Robert Oschler
  • 14,153
  • 18
  • 94
  • 227

1 Answers1

3

You are missing a piece of information, what Enum to look at.

Currently you are only passing in a string, but not the type of Enum.

The simplest way is to use a generic function

Note that contents of this are off the cuff and probably don't even compile.

public static TEnum GetEnumValue<TEnum>(string str)
    where TEnum : struct //enum is not valid here, unfortunately
{
    foreach (MemberInfo memInfo in typeof(TEnum).GetMembers())
    {
        object[] attrs = memInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);

        if (attrs != null && attrs.Length > 0)
        {
            if (((DescriptionAttribute)attrs[0]).Description == str)
            {
                return (TEnum)(object)Enum.Parse(typeof(TEnum),memInfo.Name);
            }
        }
    }

    // Unable to find a description attribute for the enum.
    return (TEnum)(object)Enum.Parse(typeof(TEnum),str);
}

Then you can use typeof(TEnum) to get the type object for the requested enumeration and do your logic.

Finally you can cast back to TEnum before returning, saving yourself the work on the calling side.

EDIT:

Added a rough example, untested.

Guvante
  • 18,775
  • 1
  • 33
  • 64
  • That's the idea I was looking for (Generics). If you're so inclined and could flesh out the code snippet a little to show a concrete example I'd appreciate it. – Robert Oschler Feb 07 '13 at 18:25
  • @RobertOschler: Added something rough, didn't even check if it compiled, let alone worked, but it would appear to be what you are looking for. – Guvante Feb 07 '13 at 19:24
  • 1
    and others reading this. The return statement that returns a value if an Attribute Description could not be found is not valid. It will trigger an Exception because typeof(TEnum) returns NULL and that causes Enum.Parse() to fail. Instead, I return an Exception at that point of the code if an attribute could not be found using the given string. Other than that it works great, thanks. – Robert Oschler Feb 08 '13 at 18:04