枚举类型(C# 编程指南)Enumeration types (C# Programming Guide)

枚举类型(也称为枚举)提供了一种有效的方式来定义可能分配给变量的一组已命名整数常量。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. 若要定义这些值,可以使用枚举类型,该类型是使用 enum 关键字声明的。To define those values, you can use an enumeration type, which is declared by using the enum keyword.

enum Day { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
enum Month : byte { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec }; 

默认情况下,枚举中每个元素的基础类型都为 int。可以使用冒号指定另一种整数类型,如上例所示。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. 有关可能的类型的完整列表,请参阅 enum(C# 参考)For a full list of possible types, see enum (C# Reference).

可以通过转换为基础类型来验证基础数值,如下例所示。You can verify the underlying numeric values by casting to the underlying type, as the following example shows.

Day today = Day.Monday;
int dayNumber =(int)today;
Console.WriteLine("{0} is day number #{1}.", today, dayNumber);

Month thisMonth = Month.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.

  • 在 Visual Studio 中,IntelliSense 列出了定义的值。In Visual Studio, IntelliSense lists the defined values.

如果未为枚举器列表中的元素指定值,则值将自动按 1 递增。When you do not specify values for the elements in the enumerator list, the values are automatically incremented by 1. 在上例中,Day.Sunday 的值为 0,Day.Monday 的值为 1,依此类推。In the previous example, Day.Sunday has a value of 0, Day.Monday has a value of 1, and so on. 创建新的 Day 对象时,如果没有明确为其分配值,它将具有默认值 Day.Sunday (0)。When you create a new Day object, it will have a default value of Day.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.

如果变量 meetingDay 的类型为 Day,那么在没有显式转换的情况下只能为其分配由 Day 定义的值。If the variable meetingDay is of type Day, then (without an explicit cast) you can only assign it one of the values defined by Day. 如果会议日期更改,可以将 Day 中的新值分配给 meetingDayAnd if the meeting day changes, you can assign a new value from Day to meetingDay:

Day meetingDay = Day.Monday;
//...
meetingDay = Day.Friday;

备注

可以将任意整数值分配给 meetingDayIt's possible to assign any arbitrary integer value to meetingDay. 例如,代码行 meetingDay = (Day) 42 不会产生错误。For example, this line of code does not produce an error: meetingDay = (Day) 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:

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.)

创建位标志枚举的方法是,应用 System.FlagsAttribute 属性并适当定义一些值,以便可以对这些值执行 ANDORNOTXOR 按位运算。You create a bit flags enum by applying the System.FlagsAttribute attribute and defining the values appropriately so that AND, OR, NOT and XOR bitwise 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".

在以下示例中,定义了名为 Days 枚举的另一个版本,命名为 DayIn the following example, another version of the Day enum, which is named Days, is defined. Days 具有 Flags 属性,且它的每个值都是 2 的若干次幂,指数依次递增。Days has the Flags attribute, and each value is assigned the next greater power of 2. 这样,你就能够创建值为 Days.Tuesday | Days.ThursdayDays 变量。This enables you to create a Days variable whose value is Days.Tuesday | Days.Thursday.

[Flags]
enum Days
{
    None      = 0b_0000_0000, // 0
    Sunday    = 0b_0000_0001, // 1
    Monday    = 0b_0000_0010, // 2
    Tuesday   = 0b_0000_0100, // 4
    Wednesday = 0b_0000_1000, // 8
    Thursday  = 0b_0001_0000, // 16
    Friday    = 0b_0010_0000, // 32
    Saturday  = 0b_0100_0000  // 64 
}
class MyClass
{
    Days meetingDays = Days.Tuesday | Days.Thursday;
}

若要在枚举上设置标志,请使用按位 OR 运算符,如以下示例所示: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 = Days.Tuesday | Days.Thursday;

// Set an additional flag using bitwise OR.
meetingDays = meetingDays | Days.Friday;

Console.WriteLine($"Meeting days are {meetingDays}");
// Output: Meeting days are Tuesday, Thursday, Friday

// Toggle a flag using bitwise XOR.
meetingDays = meetingDays ^ Days.Tuesday;
Console.WriteLine($"Meeting days are {meetingDays}");
// Output: Meeting days are Thursday, Friday

若要确定是否设置了特定标志,请使用按位 AND 运算,如以下示例所示: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 & Days.Thursday) == Days.Thursday;
Console.WriteLine($"Thursday {test == true ? "is" : "is not"} a meeting day.");
// Output: Thursday is a meeting day.

有关使用 System.FlagsAttribute 特性定义枚举类型时应考虑事项的详细信息,请参阅 System.EnumFor more information about what to consider when you define enumeration types with the System.FlagsAttribute attribute, see System.Enum.

使用 System.Enum 方法来发现和操作枚举值Using the System.Enum methods to discover and manipulate enum values

所有枚举都是 System.Enum 类型的实例。All enums are instances of the System.Enum type. 不能从 System.Enum 中派生新类,但可以使用它的方法来发现有关枚举实例中操作值的信息。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(Day), 4);
Console.WriteLine(s);
// Output: Thursday

Console.WriteLine("The values of the Day Enum are:");
foreach (int i in Enum.GetValues(typeof(Day)))
    Console.WriteLine(i);
// Output:
// The values of the Day Enum are:
// 0
// 1
// 2
// 3
// 4
// 5
// 6

Console.WriteLine("The names of the Day Enum are:");
foreach (string str in Enum.GetNames(typeof(Day)))
    Console.WriteLine(str);
// Output:
// The names of the Day Enum are:
// Sunday
// Monday
// Tuesday
// Wednesday
// Thursday
// Friday
// Saturday

有关详细信息,请参阅 System.EnumFor more information, see System.Enum.

还可以使用扩展方法创建枚举的新方法。You can also create a new method for an enum by using an extension method. 有关详细信息,请参阅如何:为枚举创建新方法For more information, see How to: Create a New Method for an Enumeration.

请参阅See also