Reputation: 14385
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:
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.
Upvotes: 1
Views: 1232
Reputation: 19221
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.
Upvotes: 3