I have a enum containing the following (for example):
In my code I use
I tried to submit an edit to Scott Ivey's answer, but it was rejected, here's yet another answer. My relatively minor edits:
1) I fixed Alex's error of System.ArgumentException: Field 'value__' defined on type 'MyClass.EnumHelperTest+MyCountryEnum' is not a field on the target object which is of type 'System.Reflection.RtFieldInfo'.
Got it from here.
2) Added a return
so you can actually copy/paste it and it'll work.
3) Changed the SortedDictionary to Dictionary because SortedDictionary always sorts by the key, in this case the string Description. There's no reason to alphabetize the Description. In fact, sorting it destroys the original order of the enum. Dictionary doesn't preserve the enum order either, but at least it doesn't imply order like SortedDictionary does.
enum MyCountryEnum
{
[Description("UK")]
UnitedKingdom = 0,
[Description("US")]
UnitedStates = 1,
[Description("FR")]
France = 2,
[Description("PO")]
Portugal = 3
}
public static string GetDescription(this Enum value)
{
var type = value.GetType();
var fi = type.GetField(value.ToString());
var descriptions = fi.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];
return descriptions.Length > 0 ? descriptions[0].Description : value.ToString();
}
public static Dictionary<string, T> GetBoundEnum<T>() where T : struct, IConvertible
{
// validate.
if (!typeof(T).IsEnum)
{
throw new ArgumentException("T must be an Enum type.");
}
var results = new Dictionary<string, T>();
FieldInfo[] fieldInfos = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static);
foreach (var fi in fieldInfos)
{
var value = (T)fi.GetValue(fi);
var description = GetDescription((Enum)fi.GetValue(fi));
if (!results.ContainsKey(description))
{
results.Add(description, value);
}
}
return results;
}
Pseudo code:
enum MyCountryEnum
{
UnitedKingdom = 0,
UnitedStates = 1,
France = 2,
Portugal = 3,
}
string[] shortCodes = new string[] {"UK", "US", "FR", "PO"};
MyCountryEnum enumValue = MyCountryEnum.UnitedKingdom;
string code = shortCodes[enumValue];
The following solution works (compiles and runs). I see two issues:
You would have to make sure the enums are in sync. (An automated test can do that for you.)
You would be relying in the fact that enums are not type safe in .NET.
enum Country
{
UnitedKingdom = 0,
UnitedStates = 1,
France = 2,
Portugal = 3
}
enum CountryCode
{
UK = 0,
US = 1,
FR = 2,
PT = 3
}
void Main()
{
string countryCode = ((CountryCode)Country.UnitedKingdom).ToString();
Console.WriteLine(countryCode);
countryCode = ((CountryCode)Country.Portugal).ToString();
Console.WriteLine(countryCode);
}
Just use the DescriptionAttribute
No need to create a dictionary if you only need to get a String representation for your enum values. See this example
[EDIT] Oh ... forgot to mention that it is more reusable than dictionaries, since you only need one common util class to help with getting the description and then all you need to do is add the DescriptionAttribute next time you add an enum value or you create a new enum with the same requirements. In the dictionary/switch solution, it is harder to maintain and it gets messy once you have many enum types.
I had to leave my work on this project for a while, and having come back to it, I had a moment of inspiration.
Rather than an enum, I created a new class like so:
public class Country
{
public const string UnitedKingdom = "UK";
public const string France = "F";
}
This way I can use Country.UnitedKingdom in my code and the value "UK" will be used.
I'm just posting this answer as an alternative solution.
Neil