Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Key value pair as enum

Tags:

c#

.net

enums

Can I have an enum which acts as a key value pair.

public enum infringementCategory
{ 
    Infringement,
    OFN
}

If I select Infringement I should get "INF0001" and if I select OFN I should get "INF0002"

Is it possible?

like image 571
Vaibhav Jain Avatar asked Feb 08 '11 10:02

Vaibhav Jain


2 Answers

You can use decorators in order to associate string representation with your enum values. Check this question: Enum ToString with user friendly strings

It will look like:

public enum infringementCategory
{ 
    [Description("INF0001")]
    Infringement,
    [Description("INF0002")]
    OFN
}

Looks more neat than using Dictionary and needs less maintain.

like image 175
anthares Avatar answered Sep 24 '22 09:09

anthares


How about these extensions:

public static class EnumExtension
{
    /// <summary>
    /// Gets the string of an DescriptionAttribute of an Enum.
    /// </summary>
    /// <param name="value">The Enum value for which the description is needed.</param>
    /// <returns>If a DescriptionAttribute is set it return the content of it.
    /// Otherwise just the raw name as string.</returns>
    public static string Description(this Enum value)
    {
        if (value == null)
        {
            throw new ArgumentNullException("value");
        }

        string description = value.ToString();
        FieldInfo fieldInfo = value.GetType().GetField(description);
        DescriptionAttribute[] attributes =
           (DescriptionAttribute[])
         fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);

        if (attributes != null && attributes.Length > 0)
        {
            description = attributes[0].Description;
        }

        return description;
    }

    /// <summary>
    /// Creates an List with all keys and values of a given Enum class
    /// </summary>
    /// <typeparam name="T">Must be derived from class Enum!</typeparam>
    /// <returns>A list of KeyValuePair&lt;Enum, string&gt; with all available
    /// names and values of the given Enum.</returns>
    public static IList<KeyValuePair<Enum, string>> ToList<T>() where T : struct
    {
        var type = typeof(T);

        if (!type.IsEnum)
        {
            throw new ArgumentException("T must be an enum");
        }

        return (IList<KeyValuePair<Enum, string>>)
                Enum.GetValues(type)
                    .OfType<Enum>()
                    .Select(e => new KeyValuePair<Enum, string>(e, e.Description()))
                    .ToArray();
    }

    public static T GetValueFromDescription<T>(string description) where T : struct
    {
        var type = typeof(T);

        if(!type.IsEnum)
        {
            throw new ArgumentException("T must be an enum");
        }

        foreach(var field in type.GetFields())
        {
            var attribute = Attribute.GetCustomAttribute(field,
                typeof(DescriptionAttribute)) as DescriptionAttribute;

            if(attribute != null)
            {
                if(attribute.Description == description)
                {
                    return (T)field.GetValue(null);
                }
            }
            else
            {
                if(field.Name == description)
                {
                    return (T)field.GetValue(null);
                }
            }
        }

        throw new ArgumentOutOfRangeException("description");
        // or return default(T);
    }
}

With this in place you can built up your enum like this:

public enum Foo
{
    [Description("Foo - Something")]
    Something,
    [Description("Foo - Anything")]
    Anything,
}

And get your list like this:

var list = EnumExtension.ToList<Foo>();
like image 39
Oliver Avatar answered Sep 23 '22 09:09

Oliver