I love enums, they’re pretty and easy to use. I use them as often as I can. Recently, I was building an application where the data model had already been defined, and could not be changed. There was a Status column in several tables of type char(1). I nice fit for enums except that it was a character instead of an integer. How to overcome this? Attributes.

Here is a sample class.

public enum TrafficLight

{

Red = 1,

Green = 2,

Yellow = 3

}

The first problem is that the database stores this value as “R”, “G”, or “Y”. To overcome this we add an custom attribute to the enum:

public enum TrafficLight

{

[TrafficLightCode(”R”)]Red = 1,

[TrafficLightCode(”G”)]Green = 2,

[TrafficLightCode(”Y”)]Yellow = 3

}

Next we need to create a class for the attribute:

[AttributeUsage(AttributeTargets.Field)]

public class TrafficLightCode : System.Attribute

{

private string trafficLightCode;

public TrafficLightCode(string LightCode)

{

trafficLightCode = LightCode;

}

public string LightCode

{

get{return trafficLightCode;}

}

}

To convert between a TrafficLightCode from the database to a TrafficLight enum, and vice versa:

public static string GetLightCodeCode(Enum value)

{

FieldInfo fi = value.GetType().GetField(value.ToString());

if (fi != null)

{

TrafficLightCodeAttribute[] attributes = (TrafficLightCodeAttribute[])fi.GetCustomAttributes(typeof(TrafficLightCodeAttribute), false);

return (attributes.Length > 0) ? attributes[0].TrafficeLightCode : value.ToString();

}

else

{

return value.ToString();

}

}

And now the hard part, coverting the character code back to the Enum when retrieving the column back from the database:

public static TrafficLight GetEnum(string code)

{

// Get the members associated with Status.

FieldInfo[] fieldInfos = typeof(TrafficLight).GetFields();

// Loop thru each member of Status

for(int i = 0; i < fieldInfos.Length; i++)

{

//Some of the fields may not have an attribute

if ( fieldInfos[i].GetCustomAttributes(true).Length > 0)

{

FieldInfo fi = fieldInfos[i];

TrafficLightCodeAttribute[] attribute = (TrafficLightCodeAttribute[])fi.GetCustomAttributes(typeof(TrafficLightCodeAttribute), false);

//Check if it matches

if (attribute[0].TrafficeLightCode == code)

{

//Get the string value, convert it to the enum value, and return it

return (TrafficLight)Enum.Parse(typeof(TrafficLight), fi.Name);

}

}

}

throw new InvalidEnumArgumentException(”Code value of ” + code + ” was not found.”);

}

Additional Uses
I use this same technique of applying attributes to enums to create user-friendly descriptions of enums so I can bind an enum to a control, and use the value of the attribute as the display value. That approach is a little easier because the .Net Framework already has a built in Description Attribute. Further reading and code samples.