mandag 6. juni 2011

Enums with string values

I have always thought that enums are pretty annoying in .NET. The problem is that they can only hold integer values, which means that it is difficult to map them to database columns which is of type VARCHAR/CHAR.

One way of solving this is with custom attributes and class extensions.

Here is the code:

First we create an attribute to hold the string value for the enum:
    public class StringValueAttribute : Attribute
    {
        /// 
        /// Holds the stringvalue for a value in an enum.
        /// 
        public string StringValue { get; protected set; }

        /// 
        /// Constructor used to init a StringValue Attribute
        /// 
        /// 
        public StringValueAttribute(string value)
        {
            StringValue = value;
        }
    }

Next we use this attribute in an enum:
    public enum Country
    {
        [StringValue("N")]
        Norway,
        [StringValue("DK")]
        Denmark,
        [StringValue("GB")]
        England
    }

The last thing we need to do is create an extension method for the Enum class and one extension method for the string class:
    public static class EnumExtensions
    {
        public static string GetStringValue(this Enum value)
        {
            // Get the type
            var type = value.GetType();

            // Get fieldinfo for this type
            var fieldInfo = type.GetField(value.ToString());

            // Get the stringvalue attributes
            var attribs = fieldInfo.GetCustomAttributes(
                typeof(StringValueAttribute), false) as StringValueAttribute[];

            // Return the first if there was a match.
            return attribs != null && attribs.Length > 0 ? attribs[0].StringValue : string.Empty;
        }
    }

    public static class StringExtensions
    {
       public static Enum GetEnumValue(this string value, Type enumType)
        {
            // Get the type
            var type = enumType;

            var fieldInfos = type.GetFields();

            foreach (var fieldInfo in fieldInfos)
            {
                var attribs = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
                if (attribs != null && attribs.Length > 0 && attribs[0].StringValue == value)
                {
                    var enumValue = (int)fieldInfo.GetValue(enumType);
                    return (Enum)Enum.ToObject(enumType, enumValue);
                }

            }

            if (Enum.IsDefined(enumType, value))
            {
                return (Enum)Enum.Parse(enumType, value);
            }
            
            throw new FaultException(value + " is not a valied object in class " + enumType.AssemblyQualifiedName);
        }
    }

Here is how to use it:
   //From string to enum
   string s = "N";
   Country c = (Country)s.GetEnumValue(typeof(Country));

   //From enum to string
   Country c = Country.Norway;
   string s = c.GetStringValue();

Ingen kommentarer:

Legg inn en kommentar