Naming Your Integers with Enums

There will be many occasions when you are writing an application where you will use integer values as flags to determine logic branching. Your main menu may provide five options, and you want the user to enter the digit related to their choice. You may have a restricted set of categories, and you want to make sure the user adheres to those restrictions. There are multiple reasons for using integer flags in software. The issue with using the actual digit as a flag is that it’s not clear to anyone looking at the code what the digits mean.


Enumeration types often referred to as “enums” provide you with a way to associate a text label to the integer value. This label will improve the readability of your code. Also, enums allow you to restrict the possible values that can be used for your logic branching. Enums are not created for the user of the application. They are used for developers working in or with your codebase, providing increased readability and reuse of your code.


Create an Enum

An enum is a value type that contains a set of named integers. This collection of constants is sometimes referred to as the “enumerator list.” Technically an enum can be used to name any numerical value (e.g., double, float, long), but doing so will require explicit casting. Generally, enums are used to display a string representation of an integer value.

Creating an enum is very similar to creating a class.


The syntax of an enum is:


[Access Modifier] ENUM keyword [Name]

{

[Enumerator List]

}


As with a class, the default modifier for an enum is INTERNAL, which means any entity within the project can utilize the enum. Although you can create an enum within a class, it’s generally a good idea to create your enums outside of any classes. This way, the enum can be used throughout the application without having to create any instances of your class.

The following code creates an enumerated list of movie ratings, in essence, assigning an integer value to each rating.


 enum MovieRating
 {
     G,
     PG,
     PG13,
     NC17,
     R,
     NR
 }

By default, Visual Studio will assign the value of 0 to the first elements then number the others consecutively. In this example, the integer value of “G” is 0. The value of “NR” is 5.

 Console.WriteLine((int) MovieRating.G);
 Console.WriteLine((int) MovieRating.NR);

This code will display the numbers 0 and 5.


Notice that I have to explicitly cast the movie rating as an integer if I want it to display the numeric value of the element. If I don’t cast the values to integers, the console window will display the string labels.


You can set the value of the first element to whatever you like, and the others will be numbered consecutively. This enum gives the value of 10 to “G,” so “NR” will have the value of 15.

 enum MovieRating
 {
 	G = 10,
 	PG,
 	PG13,
 	NC17,
 	R,
 	NR
 }

With this enum, the console would now display the numbers 10 and 15.

You also have the option to change the numbering of elements within the enumeration list.

 enum MovieRating
 {
 	G,
 	PG,
 	PG13,
 	NC17 = 10,
 	R,
 	NR
 }

With this enum, the console would now display the numbers 0 and 12. If you were wondering why you would want to do something like this, take a look at the following code snippet.

  if ((int)rating >= 10 && userAge < 17)
 {
 	Console.WriteLine("You should not watch this movie!");
 }

Instead of writing a SWITCH for every adult rating, you can just write a condition based on the integer value.


Sometimes you will want to provide a unique value to every element in the enumeration list. An excellent example of this is when working with distinct codes that your application will use to branch logic.

 enum StatusCode
 {
 	Continue = 100,
 	Ok = 200,
 	Redirection = 300,
 	BadRequest = 400,
 	ServerError = 500
 }

This SWITCH statement is clear to understand.

 switch (statusCode)
 {
 	case StatusCode.Continue:
 		break;
 	case StatusCode.Ok:
 		break;
	case StatusCode.Redirection:
 		break;
 	case StatusCode.BadRequest:
 		break;
 	case StatusCode.ServerError:
 		break;
 	default:
 		break;
 }

Whereas, this one is not.

 switch (statusCode)
 {
 	case 100:
 		break;
 	case 200:
 		break;
 	case 300:
 		break;
 	case 400:
 		break;
 	case 500:
                 break;
 	default:
 		break;
 }

Working with an Enum

As I stated earlier, an enum is a value type, so it is used in the same manner as any other value type parameter.

 int userAge;
 MovieRating rating;
 StatusCode statusCode;

You can initialize an enum variable by using the string representation of the element. You can also use an integer value to set the value of your variable. However, it will have to be explicitly cast into the enum type.

 MovieRating rating = MovieRating.PG;
 StatusCode statusCode = (StatusCode) 200;

You can also use an enum in a collection. The following code creates a dictionary to a standard message for our status code.

Dictionary<StatusCode, string> statusMessages = new Dictionary<StatusCode, string>();
 
statusMessages.Add(StatusCode.Continue, 
   "The application will continue....");
statusMessages.Add(StatusCode.Ok, 
   "The process has completed successfully.");
statusMessages.Add(StatusCode.Redirection, 
   "The process flow will not switch to another process.");
statusMessages.Add(StatusCode.BadRequest, 
   "The application can not process that request.");
statusMessages.Add(StatusCode.ServerError, 
   "The server is unavailable.");

By using the enum as the type for the dictionary key instead of an integer, we are restricting it to only values we have declared in our enum. There is no chance for an invalid integer to get into our collection.


Switch on an Enum

Using a SWITCH with an enum type is so common that when you enter your enum variable into the SWITCH statement, Visual Studio will automatically populate your CASE statements for you. The status code switch earlier in this post was generated by Visual Studio for me when I stated that I wanted to switch on the “statusCode” variable that had a StatusCode type.


Once the code is generated for me, all I have to do is write the logic for each case.

 switch (statusCode)
 {
    case StatusCode.Continue:
      // Log the event and continue on
      break;
    case StatusCode.Ok:
      // Inform the user that the process completed
      break;
    case StatusCode.Redirection:
      // Inform the use of redirection
      // Branch logic to the new process
      break;
   case StatusCode.BadRequest:
     // Instruct the user how to fix the request
     break;
   case StatusCode.ServerError:
     // Inform the user of the problem
     // Trigger support mechanism
     break;
   default:
     break;
 }

Using Enums With Classes

When declared properly, enums can be used throughout your application, including in any classes you create. Just as any other value type enums can be used as property types, be passed as parameters or be set as a return type for a method.

The following class defines a Status object that might be created every time the application status changes.

 class StatusItem
 {
 	public StatusCode Status { get; set; }
 	public DateTime StatusTime { get; set; }
 	public string MethodName { get; set; }
 
	 public StatusItem(StatusCode status, DateTime timeOccured, 
		string methodName = "Main")
 	{
 		Status = status;
 		StatusTime = timeOccured;
 		MethodName = methodName;
 	}
 }

45 views0 comments

Recent Posts

See All