C# Enums – Handling Long Descriptive String Values – Using Reflection

Consider the following scenario, you have an Enum, for which you have ‘Description’ attributes as shown below

public enum Status
 {
 [Description("Status is Incomplete")]
 Incomplete = 0,
 [Description("Status is Complete")]
 Complete = 1,
 [Description("Status is Reserved")]
 Reserved = 2,
 [Description("Stauts is Confirmed")]
 Confirmed = 3,
 [Description("Stauts is Cancelled")]
 Cancelled = 99
 }

You want to display these values in a drop down, where the text field is same as the Enum’s ‘Description’ text and the drop down value field same as the Enum’s int value.

If you have one Enum with such requirements, you would probably hard code it (I know), but in real world applications, you would have nearly 30 to 40 Enums, used at more than one place in the application, hence hard coding to the drop down is not an option. Also, let suppose we have the project requirement that the drop down should update itself when Enum is updated.

In short, we want a dynamic drop down, whose source is Enum values and if we add/remove values to the Enum, the drop down will update it self.

How to go about this ?

Lets use .NET extension and reflection and try to achieve this

The following code will use return the ‘Description Attribute’ of any Type of source using reflection

public static string GetDescriptionAttr(this T source)
 {
 FieldInfo fi = source.GetType().GetField(source.ToString());

 if (fi == null)
 return string.Empty;

 var attribute = (DescriptionAttribute) fi.GetCustomAttributes(typeof (DescriptionAttribute), false)[0];

 if (attribute == null)
 return string.Empty;

 return attribute.Description;
 }

Once this code is in place, we could write a helper function which will convert Enums to ListItemCollection where ‘Description’ attribute is used as text and Enum’s int value is used as ‘value’ field for the drop down option.

 public static ListItemCollection EnumToList(Type enumType)
 {
 var list = new ListItemCollection();

 foreach (var type in Enum.GetValues(enumType))
 {
   list.Add(new ListItem(String.Format(" {0}", type.GetDescriptionAttr()), ((int)type).ToString()));
 }

 return list;
 } 

And finally, in the code behind, you just need to pass in the Enum value to this helper method, which will use reflection and return the dynamic list for the drop down

MyDropDown.DataSource = EnumToList(typeof(Status));
MyDropDown.DataBind();

Thanks !

Advertisements

C# Enums – Handling NULL Values – Some Tips

 

As a  C# developer, we work with Enums in almost every project and use them in variety of ways.

The Enum values could be defined in the database, or they could be part of an API.  However, once we have the string value, we want to use them as Enum and perform our tasks.

Problem :

What to do if the string value is not equivalent to one of the pre-defined Enum Values

Approach :

To solve these problems, .NET framework provides methods

In .NET 4 and above, you can use Enum.TryParse<T> generic method to convert a string into an Enum

If the parsed value is not equivalent to one of the Enum values, you could return a null and then check for null every where in the code before using this Enum.

Consider the following Enum

 

 /// <summary>
 /// Direction Enum
 /// </summary>
 public enum Direction
 {
 /// <summary>
 /// NORTH direction
 /// </summary>
 NORTH = 1,
 /// <summary>
 /// SOUTH Direction
 /// </summary>
 SOUTH = 2,
 /// <summary>
 /// EAST Direction
 /// </summary>
 EAST = 3,
 /// <summary>
 /// WEST Direciton
 /// </summary>
 WEST = 4
 
 }

This is a very simple Direction Enum and expected values are 4 known directions.

Consider we are building a console application and asking user to input one the direction and then trying to convert it into one of our Enum with following function

 

 /// Parse the input  Enum value
 /// </summary>
 /// <param name="input"></param>
 /// <returns></returns>
 private static Direction ParseInput(string input)
 {
 if (String.IsNullOrEmpty(input))
 return null;

 if (String.IsNullOrWhiteSpace(input))
 return null;

 Direction direction;
 if (Enum.TryParse<Direction>(input.ToUpper(), out direction))
 {
 return direction;
 }

return null;

 }

 

This is absolutely fine piece of code, which will return you correct Enum value otherwise it will return null.

But whenever this function will be called in rest of the project, you have to check for the ‘null’ value exception all the time

Something like

var direction = ParseInput(Console.ReadLine())

if (direction != null)
{
  //then your logic  
}

 

How about adding an extra Enum to your class as NONE and returning it instead of the ‘null’ value?

 

Your updated Enum would be

 

 /// <summary>
 /// Direction Enum
 /// </summary>
 public enum Direction
 {
 /// <summary>
 /// NORTH direction
 /// </summary>
 NORTH = 1,
 /// <summary>
 /// SOUTH Direction
 /// </summary>
 SOUTH = 2,
 /// <summary>
 /// EAST Direction
 /// </summary>
 EAST = 3,
 /// <summary>
 /// WEST Direciton
 /// </summary>
 WEST = 4,
 /// <summary>
 /// NONE direction
 /// </summary>
 NONE = 99

 
 }

 

And your updated function would be

/// <summary>
 /// Parse the input  Enum value
 /// </summary>
 /// <param name="input"></param>
 /// <returns></returns>
 private static Direction ParseInput(string input)
 {
 if (String.IsNullOrEmpty(input))
 return Direction.NONE;

 if (String.IsNullOrWhiteSpace(input))
 return Direction.NONE;

 Direction direction;
 if (Enum.TryParse<Direction>(input.ToUpper(), out direction))
 {
 return direction;
 }

return Direction.NONE;

 }


This approach would solve your the problem of checking for ‘null’ value all over the project and you can simply use a switch() statement every time this function is called.

Thanks !