Enum to dictionary

by Alex Siepman 14. April 2012 10:30

Problem

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.

Solution

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:

Value
A different value
Different description

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)) 
{
return String.Concat(" ", original.ToString(CultureInfo.InvariantCulture).ToLower());
} return original.ToString(); }

Optional

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));
}

Example

ConvertEnumToDictionaryEnumString<TestEnum>();

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading

About the author

I am a software architect at Roxit and also a C# Developer. My main interests in the area of ​​C# are LINQ and generics

Visit my personal homepage (Dutch) for more info about me.

Month List

Page List