In a previous project we stored the values of an enum in a database. That made it easy to fill listboxes and comboboxes. It also helps to ensure data integrity. Storing enums means a violations of the most important rule for developers: single point of definition.
A better option is a dictionary with easy to read descriptions.
Example of an enum:
[DataContract]
enum TestEnum
{
Value = 2,
ADifferentValue,
[EnumMember(Value = "Different description")]
OriginalValue
}
In this case you want a dictionary to fill the listboxes with the enum value as the key and these values:
Note the extra spaces and lowercase characters.
This can be done this way:
public static IDictionary<T, string> ConvertEnumToDictionaryEnumString<T>()
{
return ConvertEnumToDictionaryStringEnum<T>().ToDictionary(x => x.Value, y => y.Key);
}
public static IDictionary<string, T> ConvertEnumToDictionaryStringEnum<T>()
{
CheckIfTIsAnEnum<T>();
var tValues = Enum.GetValues(typeof(T)).Cast<T>();
return tValues.ToDictionary(c => GetDescriptionEnumObject(c));
}
private static void CheckIfTIsAnEnum<T>()
{
if (typeof(T).BaseType != typeof(Enum))
{
throw new InvalidCastException("The type must be an enum");
}
}
Now we still need to implement the GetDescriptionEnumObject() method. We could do that with regular expressions but that is is hard to debug so I did that the hard way:
private static string GetDescriptionEnumObject(object enumObject)
{
string result;
FieldInfo fieldInfo = enumObject.GetType().GetField(enumObject.ToString());
var fieldInfoEnumMembers = (EnumMemberAttribute[])fieldInfo.GetCustomAttributes(typeof(EnumMemberAttribute), true);
var fieldInfoEnumMember = fieldInfoEnumMembers.FirstOrDefault();
if (fieldInfoEnumMember == null) // No EnumMember-Attribute
{
result = ConvertToReadableText(enumObject.ToString());
}
else // Has an EnumMember-Attribute
{
if (fieldInfoEnumMember.Value == null) // Attribute not filled with text
{
result = ConvertToReadableText(enumObject.ToString()); // Do the same as if there is no attribute
}
else // The attribute is filled with text
{
result = fieldInfoEnumMember.Value; // Return text in the attribute
}
}
return result;
}
private static string ConvertToReadableText(string originalText)
{
if (originalText == null || originalText.Length < 2)
{
return originalText;
}
var collectionChars = originalText.Substring(1).Select(ConvertCharToReadableText); // Start on second position
return originalText.Substring(0, 1) + String.Concat(collectionChars); // First char remains the same
}
private static string ConvertCharToReadableText(char original)
{
if (char.IsUpper(original)) <br> {<br> return String.Concat(" ", original.ToString(CultureInfo.InvariantCulture).ToLower());<br> }
return original.ToString();
}
In case you also need an int-string dictionary:
public static IDictionary<int, string> ConvertEnumToDictionaryIntString<T>()
{
// Swap Key en value
return ConvertEnumToDictionaryStringInt<T>().ToDictionary(x => x.Value, y => y.Key);
}
public static IDictionary<string, int> ConvertEnumToDictionaryStringInt<T>()
{
return ConvertEnumToDictionaryStringEnum<T>().ToDictionary(x => x.Key, y => Convert.ToInt32(y.Value));
}
ConvertEnumToDictionaryEnumString<TestEnum>();