Enums

An enum is a special value type that lets you specify a group of named numeric constants. For example:

public enum BorderSide { Left, Right, Top, Bottom }

We can use this enum type as follows:

BorderSide topSide = BorderSide.Top;
bool isTop = (topSide == BorderSide.Top);   // true

Each enum member has an underlying integral value. By default, the underlying values are of type int, and the enum members are assigned the constants 0, 1, 2... (in their declaration order). You may specify an alternative integral type, as follows:

public enum BorderSide : byte { Left, Right, Top, Bottom }

You may also specify an explicit integral value for each member:

public enum BorderSide : byte
 { Left=1, Right=2, Top=10, Bottom=11 }

The compiler also lets you explicitly assign some of the enum members. The unassigned enum members keep incrementing from the last explicit value. The preceding example is equivalent to:

public enum BorderSide : byte
 { Left=1, Right, Top=10, Bottom }

You can convert an enum instance to and from its underlying integral value with an explicit cast:

int i = (int) BorderSide.Left;
BorderSide side = (BorderSide) i;
bool leftOrRight = (int) side <= 2;

You can also explicitly cast one enum type to another; the translation then uses the members’ underlying integral values.

The numeric literal 0 is treated specially in that it does not require an explicit cast:

BorderSide b = 0;    // No cast required
if (b == 0) ...

In this particular example, BorderSide has no member with an integral value of 0. This does not generate an error: a limitation of enums is that the compiler and CLR do not prevent the assignment of integrals whose values fall outside the range of members:

BorderSide b = (BorderSide) 12345;
Console.WriteLine (b);              // 12345

You can combine enum members. To prevent ambiguities, members of a combinable enum require explicitly assigned values, typically in powers of two. For example:

[Flags]
public enum BorderSides
 { Left=1, Right=2, Top=4, Bottom=8 }

By convention, a combinable enum type is given a plural rather than singular name. To work with combined enum values, you use bitwise operators, such as | and &. These operate on the underlying integral values:

BorderSides leftRight =
  BorderSides.Left | BorderSides.Right;

if ((leftRight & BorderSides.Left) != 0)
  Console.WriteLine ("Includes Left");   // Includes Left

string formatted = leftRight.ToString(); // "Left, Right"

BorderSides s = BorderSides.Left;
s |= BorderSides.Right;
Console.WriteLine (s == leftRight);      // True

The Flags attribute should be applied to combinable enum types; if you fail to do this, calling ToString on an enum instance emits a number rather than a series of names.

For convenience, you can include combination members within an enum declaration itself:

[Flags] public enum BorderSides
{
  Left=1, Right=2, Top=4, Bottom=8,
  LeftRight = Left | Right,
  TopBottom = Top  | Bottom,
  All       = LeftRight | TopBottom
}

The operators that work with enums are:

=   ==   !=   <   >   <=   >=   +   −   ^  &  |   ˜
+=  −=   ++   −   sizeof

The bitwise, arithmetic, and comparison operators return the result of processing the underlying integral values. Addition is permitted between an enum and an integral type, but not between two enums.