Back to Basics: Enumerators and the Importance of Well Named Variables

Your ability to read code is tantamount to your success as a developer. It’s not just about understanding of the syntax within the language. A lot of proper readability comes from you and how clean you are as a programmer.

var price1 = 15.99;
var price2 = 20.99;
var price3 = 35.99;

Looking at this code, you can derive almost no information about what these are by looking at them. You know they are a set of prices, but what prices? When you have to add a number to a variable name like in the example above, you need to go back and be more descriptive about your variable names.

var memberPrice = 15.99;
var salePrice = 20.99;
var regularPrice = 35.99;

Now, looking at this code, you can derive a good amount of information about what each number represents. As you read on through the code that this snippet could have came from, you will no guesses on which price is what.

Back to Basics: Enumerators and Well Named Variables

This may seem like really simple and basic stuff, and it is. But, it’s a crucial point that can’t be repeated enough. With poor variable naming you’ll have a difficult time reading your code down the road when you need to add features/fix bugs. Even worse, if one of your dev pals needs to take on the project they’re going to be lost ten fold more than you would be. Taking on someone else’s code can be difficult enough without silly variable names.

Enumerators are an amazing tool for two main reasons:

1. It can make code much, much easier to read

2. You use them to define and restrict dataflow between methods, or on a comparison. This eliminates many headaches of error checking, and also tells any devs that need to take on your code exactly what should be expected within the code itself.

Before touching on the first point, let’s get a general overview of just exactly what an Enumerator is.

What is an Enumerator?

– Enumerators are constant values.
– They can be assigned specific integer values.
– They can be used for string comparison as well as integer.
– They define descriptive constant values.

**Do not ever use an Enumerator to store a value like you would a variable.

Examples: Trickier than you think

So let’s look at an example:

public enum ProductAttribute
{
	Price = 56,
	SalePrice = 45,
	Quantity = 5,
}

This example is a bit tricky, and I did this on purpose.

What this enumerator DOES NOT mean:

The price of a product IS NOT 56.
The sale price of a product IS NOT 45.
The quantity IS NOT 5.
These values are not representative of a products data at all.

What this enumerator DOES mean

– The Id of the attribute Price in a database is 56
– The Id of the attribute SalePrice in the database is 45
– The Id of the attribute Quantity in the database is 5

Using enumerators to reflect actual Ids from a database or data source is a great reason to assign integers to your enumerators. Just be careful if those Ids change!

So to put this to test. Let’s make a little method:

public void UpdateAttribute(string value, int attributeId)
{
//code goes here
}

In this example I’m passing in two arguments. A string and an integer. The string represents an actual value, and the integer represents a unique Id in the database. So to call this method I could do:

UpdateAttribute("24.99", 56);

What this is doing is updating Price to 24.99. This logic will work based on the examples I’ve used above. It will execute fine and everything will be hunky-dory. However, what if a dev pals grabs your code and takes a look? What is he going to think looking at that above code? He’s going to have no idea what is happening there.

You could make the argument that you could comment “//Updating price” but two flaws with that logic.

1. You might not be passing a static number. You may be passing in attributeId dynamically
2. Having a lot of comments, to me, is frustrating to read. Comments are great, and they do help everyone, but if they’re littered in half your code, you’ve got a bloaty, messy looking code file.

A fellow dev pal should be able to infer most of what your code is doing just from looking at the code itself. It’s a good idea every once in a while to have someone else look at your code and just ask them to tell you what they see is happening in the code. If they can’t answer that question well you need to go back and make the unreadable code, readable.

So let’s use enumerators on this method now

Public void UpdateAttribute(string value, ProductAttribute attribute)
{
	var attributeId = (int)attribute;
	//code goes here
}

This method still takes two arguments. A string again, that represents the actual value, and an enumerator ProductAttribute.
You’ll also notice one line of code within the method. This line of code takes the integer value from the enumerator you pass in. so if I pass in

UpdateAttribute(“23.99”, ProductAttribute.Price);

attributeId will parse out to 56.

The exact same result will happen between the method where we passed in an int and the method where we passed in the enumerator. There is absolutely no processing advantage to using an enumerator, but it makes the code incredibly easier to read. And forces developers to only pass in pre-defined values. No error checking for strange numbers required! Any dev pal will be able to figure out what’s going on that line of code without any comment or explanation.

This is only one line of code I “cleaned” up from possible hundreds of lines in a code file. It may not seem that impactful from one solitary example, but when you make 100s of code files more readable, your dev pals (and your future self!) will thank you you took the time to make clean, readable code.

Example #2

Let’s look at another example

public enum PayType
{
	CreditCard,
	PayPal,
	StoreCredit,
}

Notice I didn’t define integers on this example, I usually do anyways just out of habit, but it’s never actually necessary, especially if you don’t need them.

Let’s look at a quick example of how we could use this.

public void ProcessPayment(PayType paymentType, OrderInformation orderInfo)
{
	Switch(paymentType)
	{
		case PayType.CreditCard:
			//process cc payment
			break;
		case PayType.Paypal;
			//process paypal payment
			break;
	}
}

This method takes two arguments Enumerator PayType, and class OrderInformation (which is not necessary to know what it is for the sake of this example)

If we passed paymentType in as a string we could pass it in as

ProcessPayments("credditcard", orderInfo);
ProcessPayments("paypal", orderInfo);

etc. etc. but this could cause problems. What if “credit card” got passed in? What if “Paypal” got passed in? You can use string operations to make anything passed in as generic as possible (ToLowerInvariant(), Replace(” “, “”) for example), but what if someone passed in “visa” instead of credit card? Are you going to start supporting paytypes you don’t want? Not process the payment? That’s going to cause issues. Skip all the string operations and most error checking by forcing people to pass in the pre-defined paytype.

ProcessPayments(PayType.CreditCard, orderInfo);
ProcessPayments(PayType.Paypal, orderInfo);

A little bit easier to read, the most important part about this example is how you’re restricting what you’re allowing the method to consume. Someone literally is not allowed to pass in.

ProcessPayments(PayType.credit_card, orderInfo);
ProcessPayments(PayType.Visa, orderInfo);

This will never ever be seen unless thes values are explicitly added to the enumerator in your code beforehand. You won’t need to error check for invalid PayTypes being passed in, the IDE will do that for you, and will fail the build.

Time consuming, but well worth the effort!

Making code easy to read and simple to use is one of the most important, and most overlooked aspects of programming. It may look like it takes more time to code this out with enumerators, but the time saved not error checking, and the time saved on making edits in the future, is far greater than the few seconds it takes to define an enumerator or name a variable descriptive and appropriately.