A constant lets us define a name for a value in one place in our code.
An enum is like defining a set of constants and lets us declare variables, properties, and parameters that can only use one of those constants.
For example, suppose we have a SalesOrder
class for orders we receive on a website, and each SalesOrder
can have a status - perhaps New, Shipped, Canceled, etc.
We could do it like this:
public class SalesOrder
{
public string OrderStatus {get;set;}
But then someone could set that property to something completely invalid, like
order.OrderStatus = "Hello!";
We could decide that we'll give each status a number instead to prevent someone using some crazy value. So we change it to
public class SalesOrder
{
public int OrderStatusCode {get;set;}
and we decide that 1 = New, 2 = Shipped, 3 = Canceled, etc. But that still doesn't fix anything, because someone can set OrderStatusCode = -666
and we're still messed up.
In any one of these cases we could improve on this with constants, like
const string SHIPPED_ORDER_STATUS = "Shipped";
or
const int NEW_ORDER_STATUS_CODE = 1;
But that still doesn't really solve the problem. It helps us to do this:
order.OrderStatusCode = NEW_ORDER_STATUS_CODE;
and that's good. But it still doesn't prevent this:
order.OrderStatusCode = 555; //No such order status code!
An enum
lets us do this:
public enum OrderStatuses
{
New,
Shipped,
Canceled
}
public class SalesOrder
{
public OrderStatuses OrderStatus {get;set;}
Now it's impossible to set OrderStatus
to any invalid value. It can only be one of the values in OrderStatuses
.
Comparisons become a lot easier too. Instead of
if(string.Equals(order.OrderStatus,"shipped",Ordinal.IgnoreCase))
or
if(order.OrderStatusCode == 3) //What does three mean? Magic number!
We can do
if(order.OrderStatus == OrderStatuses.Shipped)
Now it's readable and easier to maintain. The compiler will prevent using any invalid value. If you decide you want to change the name of a value in OrderStatuses
you can just right-click and rename it. You can't do that with a string
or an int
.
So an enum
is very useful in that scenario - if we want to have a type with a limited, predefined set of values.
The most common use for constants is if we're putting a string or a number in our code that either repeats or has no apparent meaning, like
if(myString.Length > 434) //What is 434? Why do I care if it's more than 434?
We might declare a constant like
const int MAX_FIELD_LENGTH = 434;
Now this makes sense:
if(myString.Length > MAX_FIELD_LENGTH) //Now it's obvious what this check is for.
It's a small detail but it signals our intent and keeps us from storing a value in multiple places.