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:
Underlying values are of type int
.
The constants 0, 1, 2
… are automatically assigned
in the declaration order of the enum
members.
You may specify an alternative integral type, as follows:
public enum BorderSide : byte
{ Left, Right, Top, Bottom }
You may also specify an explicit underlying value for each enum 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 horizontal = (int) side <= 2;
You can also explicitly cast one enum type to another. Suppose HorizontalAlignment
is defined as follows:
public enum HorizontalAlignment { Left = BorderSide.Left, Right = BorderSide.Right, Center }
A translation between the enum types uses the underlying integral values:
HorizontalAlignment h = (HorizontalAlignment) BorderSide.Right; // same as: HorizontalAlignment h = (HorizontalAlignment) (int) BorderSide.Right;
The numeric literal 0
is treated specially by the
compiler in an enum
expression and does not require an
explicit cast:
BorderSide b = 0; // no cast required if (b == 0) ...
There are two reasons for the special treatment of 0
:
The first member of an enum is often used as the “default” value.
For combined enum types, 0
means “no flags.”
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 }
To work with combined enum values, use bitwise operators, such as | and &. These operate on the underlying integral values:
BorderSides leftRight = BorderSides.Left | BorderSides.Right; if ((leftRight & BorderSides.Left) != 0) System.Console.WriteLine ("Includes Left"); // OUTPUT: "Includes Left" string formatted = leftRight.ToString(); // formatted is "Left, Right" BorderSides s = BorderSides.Left; s |= BorderSides.Right; Console.WriteLine (s == leftRight); // True s ^= BorderSides.Right; // Toggles BorderSides.Right Console.WriteLine (s); // Left
By convention, the Flags
attribute should always be
applied to an enum type when its members are combinable. If you declare such an enum
without the Flags
attribute, you can still combine members, but calling ToString
on an enum
instance will emit a
number rather than a series of names.
By convention, a combinable enum type is given a plural rather than singular name.
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 and subtraction are permitted between an enum
and an integral type but not between two enums
.