An enumeration type (also named an enumeration or an enum) provides an efficient way to define a set of named integral constants that may be assigned to a variable. For example, assume that you have to define a variable whose value will represent a day of the week. There are only seven meaningful values which that variable will ever store. To define those values, you can use an enumeration type, which is declared by using the enum keyword.
C#
enum Days { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
enum Months : byte { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec };
By default the underlying type of each element in the enum is int. You can specify another integral numeric type by using a colon, as shown in the previous example. For a full list of possible types
You can verify the underlying numeric values by casting to the underlying type, as the following example shows.
C#
Days today = Days.Monday;
int dayNumber =(int)today;
Console.WriteLine("{0} is day number #{1}.", today, dayNumber);
Months thisMonth = Months.Dec;
byte monthNumber = (byte)thisMonth;
Console.WriteLine("{0} is month number #{1}.", thisMonth, monthNumber);
// Output:
// Monday is day number #1.
// Dec is month number #11.
The following are advantages of using an enum instead of a numeric type:
-
You clearly specify for client code which values are valid for the variable.
-
In Visual Studio, IntelliSense lists the defined values.
When you do not specify values for the elements in the enumerator list, the values are automatically incremented by 1. In the previous example,Days.Sunday has a value of 0, Days.Monday has a value of 1, and so on. When you create a new Days object, it will have a default value of Days.Sunday (0) if you do not explicitly assign it a value. When you create an enum, select the most logical default value and give it a value of zero. That will cause all enums to have that default value if they are not explicitly assigned a value when they are created.
If the variable meetingDay is of type Days, then (without an explicit cast) you can only assign it one of the values defined by Days. And if the meeting day changes, you can assign a new value from Days to meetingDay:
C#
Days meetingDay = Days.Monday;
//...
meetingDay = Days.Friday;
|
It is possible to assign any arbitrary integer value to meetingDay. For example, this line of code does not produce an error: meetingDay = (Days) 42. However, you should not do this because the implicit expectation is that an enum variable will only hold one of the values defined by the enum. To assign an arbitrary value to a variable of an enumeration type is to introduce a high risk for errors. |
You can assign any values to the elements in the enumerator list of an enumeration type, and you can also use computed values:
C#
enum MachineState
{
PowerOff = 0,
Running = 5,
Sleeping = 10,
Hibernating = Sleeping + 5
}
Enumeration Types as Bit Flags
You can use an enumeration type to define bit flags, which enables an instance of the enumeration type to store any combination of the values that are defined in the enumerator list. (Of course, some combinations may not be meaningful or allowed in your program code.)
You create a bit flags enum by applying the System.FlagsAttribute attribute and defining the values appropriately so that AND, OR, NOT and XORbitwise operations can be performed on them. In a bit flags enum, include a named constant with a value of zero that means "no flags are set." Do not give a flag a value of zero if it does not mean "no flags are set".
In the following example, another version of the Days enum, which is named Days2, is defined. Days2 has the Flags attribute and each value is assigned the next greater power of 2. This enables you to create a Days2 variable whose value is Days2.Tuesday and Days2.Thursday.
C#
[Flags]
enum Days2
{
None = 0x0,
Sunday = 0x1,
Monday = 0x2,
Tuesday = 0x4,
Wednesday = 0x8,
Thursday = 0x10,
Friday = 0x20,
Saturday = 0x40
}
class MyClass
{
Days2 meetingDays = Days2.Tuesday | Days2.Thursday;
}
To set a flag on an enum, use the bitwise OR operator as shown in the following example:
// Initialize with two flags using bitwise OR.
meetingDays = Days2.Tuesday | Days2.Thursday;
// Set an additional flag using bitwise OR.
meetingDays = meetingDays | Days2.Friday;
Console.WriteLine("Meeting days are {0}", meetingDays);
// Output: Meeting days are Tuesday, Thursday, Friday
// Remove a flag using bitwise XOR.
meetingDays = meetingDays ^ Days2.Tuesday;
Console.WriteLine("Meeting days are {0}", meetingDays);
// Output: Meeting days are Thursday, Friday
To determine whether a specific flag is set, use a bitwise AND operation, as shown in the following example:
// Test value of flags using bitwise AND.
bool test = (meetingDays & Days2.Thursday) == Days2.Thursday;
Console.WriteLine("Thursday {0} a meeting day.", test == true ? "is" : "is not");
// Output: Thursday is a meeting day.
Using the System.Enum Methods to Discover and Manipulate Enum Values
All enums are instances of the System.Enum type. You cannot derive new classes from System.Enum, but you can use its methods to discover information about and manipulate values in an enum instance.
string s = Enum.GetName(typeof(Days), 4);
Console.WriteLine(s);
Console.WriteLine("The values of the Days Enum are:");
foreach (int i in Enum.GetValues(typeof(Days)))
Console.WriteLine(i);
Console.WriteLine("The names of the Days Enum are:");
foreach (string str in Enum.GetNames(typeof(Days)))
Console.WriteLine(str);