BlackWasp
C# Programming
.NET 1.1

C# Constants and Enumerations

The forty-eighth part of the C# Fundamentals tutorial examines the use of constants and enumerations.  These provide two methods of describing non-changing values using descriptive words rather than "magic numbers" to improve code readability.

Why Use Constants?

A C# constant is similar to a variable in that it gives a defined name to a value.  However, a constant differs from a standard variable because once defined, the value assigned to the constant can never be changed.  The chief benefit of constants is their assistance in creating self-documenting code as well as allowing the declaration of key values in a single place, which permits easy maintenance should the value need to be updated and the software recompiled.

To demonstrate the self-documenting value of constants, consider the following line of code:

price += (price * 0.175) + 4.99;

You could probably work out what the developer was trying to do here.  A price is being increased by 17.5% and then a further £4.99 is being added.  However, if the code is rewritten using constants instead of magic numbers, the purpose becomes obvious.

price += (price * ValueAddedTax) + DeliveryCharge;

Not only is this second variant easier to read, it now allows the definitions of tax rules and delivery charges to be changed in a single location.  The constant values can be modified once and the new value automatically be used many times throughout the code.  NB: The scope of a constant is defined in a similar manner to variable scopes.

Declaring a Constant

A constant is declared using similar syntax to any other variable.  However, to indicate that the value is fixed and may not be changed at run-time, the const keyword is used as a prefix to the data type.  Here is how the previous example code looks with the constant definitions included:

double price = 100;
const double ValueAddedTax = 0.175;
const double DeliveryCharge = 4.99;

price += (price * ValueAddedTax) + DeliveryCharge;

Constants must be possible to evaluate at compile-time.  This limits the use of constants to values that can be expressed directly in the source code such as numeric values and strings.  Values that cannot be initialised without the use of a constructor are not permitted, meaning reference type constants may only be null.

Enumerations

An enumeration, or enumerator list, declares a series of constants, each of which has an integer value.  Enumerator lists are useful for defining sequences and states, particularly when there is a natural progression through those states.  This is because each constant in the list can be formatted and compared using either its name or value.

Defining and Enumeration

The simplest method for declaring an enumeration is to list all of the possible names in a set of braces after the enumeration's name.  To indicate that an enumerator list is being defined, the enum keyword is used as a prefix to the name.  In this case, the first item in the list is assigned the value zero and each subsequent item is incremented.

This simple declaration defines a constant for every month of the year:

enum Month { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec }

Using Enumerated Values

Once an enumeration is declared within a class, all of the methods of the class are able to utilise the values of the list using the names of the list and of the individual item separated using the member access operator (.)  The following example shows how a value from the list can be retrieved and outputted as either an integer value or as a string.

class Program
{
    enum Month { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec }

    static void Main(string[] args)
    {
        Console.WriteLine((int)Month.Feb);                  // Outputs "1"
        Console.WriteLine(Month.Feb);                       // Outputs "Feb"
    }
}

As the enumeration provides a list of linked numeric values, it is also possible to perform simple operations on the integer representations.  In the next sample, a new variable is declared of the enumerated type.  Simple mathematical operators are then used to modify the value.  Note that when the range of the enumeration is exceeded, the values revert back to the integer representations.

class Program
{
    enum Month { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec }

    static void Main(string[] args)
    {
        Month mon = Month.Jan;

        for (int i = 0; i<=12; i++)
            Console.WriteLine(mon++);
    }
}

/* OUTPUT

Jan
Feb
Mar
Apr
May
Jun
Jul
Aug
Sep
Oct
Nov
Dec
12

*/

Specifying The List Values

In many cases you will want the enumerator list values to begin with an integer value that is non-zero.  You may even wish to individually specify each value for the list.  This can be achieved by assigning a value to any of the listed items using a standard assignment operator (=).  If you miss a value for any item in the list, it is automatically assigned a value that is one greater than the previous item.

class Program
{
    enum IssueStatus
    {
        New = 1,
        Open,
        Closed,
        Cancelled = -1
    }

    static void Main(string[] args)
    {
        Console.WriteLine((int)IssueStatus.New);            // Outputs "1"
        Console.WriteLine((int)IssueStatus.Open);           // Outputs "2"
        Console.WriteLine((int)IssueStatus.Closed);         // Outputs "3"
        Console.WriteLine((int)IssueStatus.Cancelled);      // Outputs "-1"
    }
}

NB: The compiler will allow you to define multiple items with the same integer value.  However, this is inadvisable as the results can be unpredictable.

Changing the Enumeration Base Type

Normally when an enumeration is declared, every constant in the list is a 32-bit integer, or int.  However, this can be overridden to any other standard integer type except for char by adding a colon (:) and the alternative type after the enumeration's name.

enum IssueStatus : short
{
    New = 1,
    Open,
    Closed,
    Cancelled = -1
}
Link to this Page16 August 2007
RSS RSS Feed
100 users on-line