枚举Enums

枚举类型 是声明一组命名常量 (值类型) 的非重复值类型。An enum type is a distinct value type (Value types) that declares a set of named constants.

示例The example

enum Color
{
    Red,
    Green,
    Blue
}

Color使用成员、和声明名为的枚举类型 Red Green Bluedeclares an enum type named Color with members Red, Green, and Blue.

枚举声明Enum declarations

枚举声明声明一个新的枚举类型。An enum declaration declares a new enum type. 枚举声明以关键字开头 enum ,并定义枚举的名称、可访问性、基础类型和成员。An enum declaration begins with the keyword enum, and defines the name, accessibility, underlying type, and members of the enum.

enum_declaration
    : attributes? enum_modifier* 'enum' identifier enum_base? enum_body ';'?
    ;

enum_base
    : ':' integral_type
    ;

enum_body
    : '{' enum_member_declarations? '}'
    | '{' enum_member_declarations ',' '}'
    ;

每个枚举类型都有一个对应的整型类型,称为枚举类型的 基础类型Each enum type has a corresponding integral type called the underlying type of the enum type. 此基础类型必须能够表示枚举中定义的所有枚举器值。This underlying type must be able to represent all the enumerator values defined in the enumeration. 枚举声明可以显式声明、、、、、或的基础类型 byte sbyte short ushort int uint long ulongAn enum declaration may explicitly declare an underlying type of byte, sbyte, short, ushort, int, uint, long or ulong. 请注意, char 不能用作基础类型。Note that char cannot be used as an underlying type. 不显式声明基础类型的枚举声明具有基础类型 intAn enum declaration that does not explicitly declare an underlying type has an underlying type of int.

示例The example

enum Color: long
{
    Red,
    Green,
    Blue
}

声明基础类型为的枚举 longdeclares an enum with an underlying type of long. 开发人员可以选择使用基础类型 long (如本示例所示),以允许使用范围内但不在的范围内的值 long int ,或者将此选项保留为将来的选项。A developer might choose to use an underlying type of long, as in the example, to enable the use of values that are in the range of long but not in the range of int, or to preserve this option for the future.

枚举修饰符Enum modifiers

Enum_declaration 可以选择性地包含一系列枚举修饰符:An enum_declaration may optionally include a sequence of enum modifiers:

enum_modifier
    : 'new'
    | 'public'
    | 'protected'
    | 'internal'
    | 'private'
    ;

同一修饰符在一个枚举声明中多次出现是编译时错误。It is a compile-time error for the same modifier to appear multiple times in an enum declaration.

枚举声明的修饰符与) 类修饰符 (类 修饰符 的修饰符具有相同的含义。The modifiers of an enum declaration have the same meaning as those of a class declaration (Class modifiers). 但请注意, abstract sealed 在枚举声明中不允许和修饰符。Note, however, that the abstract and sealed modifiers are not permitted in an enum declaration. 枚举不能是抽象的并且不允许派生。Enums cannot be abstract and do not permit derivation.

枚举成员Enum members

枚举类型声明的主体定义零个或多个枚举成员,这是枚举类型的命名常量。The body of an enum type declaration defines zero or more enum members, which are the named constants of the enum type. 两个枚举成员不能具有相同的名称。No two enum members can have the same name.

enum_member_declarations
    : enum_member_declaration (',' enum_member_declaration)*
    ;

enum_member_declaration
    : attributes? identifier ('=' constant_expression)?
    ;

每个枚举成员都有一个关联的常量值。Each enum member has an associated constant value. 此值的类型是包含枚举的基础类型。The type of this value is the underlying type for the containing enum. 每个枚举成员的常数值必须在该枚举的基础类型的范围内。The constant value for each enum member must be in the range of the underlying type for the enum. 示例The example

enum Color: uint
{
    Red = -1,
    Green = -2,
    Blue = -3
}

导致编译时错误,因为常量值 -1-2-3 不在基础整型类型的范围内 uintresults in a compile-time error because the constant values -1, -2, and -3 are not in the range of the underlying integral type uint.

多个枚举成员可能共享相同的关联值。Multiple enum members may share the same associated value. 示例The example

enum Color 
{
    Red,
    Green,
    Blue,

    Max = Blue
}

显示一个枚举,其中两个枚举成员-- BlueMax --具有相同的关联值。shows an enum in which two enum members -- Blue and Max -- have the same associated value.

枚举成员的关联值是隐式或显式分配的。The associated value of an enum member is assigned either implicitly or explicitly. 如果枚举成员的声明具有 constant_expression 初始值设定项,则该常量表达式的值将隐式转换为枚举的基础类型,这是枚举成员的关联值。If the declaration of the enum member has a constant_expression initializer, the value of that constant expression, implicitly converted to the underlying type of the enum, is the associated value of the enum member. 如果枚举成员的声明没有初始值设定项,则将隐式设置其关联值,如下所示:If the declaration of the enum member has no initializer, its associated value is set implicitly, as follows:

  • 如果枚举成员是枚举类型中声明的第一个枚举成员,则其关联值为零。If the enum member is the first enum member declared in the enum type, its associated value is zero.
  • 否则,枚举成员的关联值将通过将每个按日的枚举成员的关联值增加一个来获得。Otherwise, the associated value of the enum member is obtained by increasing the associated value of the textually preceding enum member by one. 这一增加的值必须在可由基础类型表示的值范围内,否则将发生编译时错误。This increased value must be within the range of values that can be represented by the underlying type, otherwise a compile-time error occurs.

示例The example

using System;

enum Color
{
    Red,
    Green = 10,
    Blue
}

class Test
{
    static void Main() {
        Console.WriteLine(StringFromColor(Color.Red));
        Console.WriteLine(StringFromColor(Color.Green));
        Console.WriteLine(StringFromColor(Color.Blue));
    }

    static string StringFromColor(Color c) {
        switch (c) {
            case Color.Red: 
                return String.Format("Red = {0}", (int) c);

            case Color.Green:
                return String.Format("Green = {0}", (int) c);

            case Color.Blue:
                return String.Format("Blue = {0}", (int) c);

            default:
                return "Invalid color";
        }
    }
}

输出枚举成员名称及其关联值。prints out the enum member names and their associated values. 输出为:The output is:

Red = 0
Green = 10
Blue = 11

原因如下:for the following reasons:

  • 枚举成员 Red 的值为零,因为它没有初始值设定项,并且是第一个枚举成员) ,所以它会自动赋予 (;the enum member Red is automatically assigned the value zero (since it has no initializer and is the first enum member);
  • 为枚举成员 Green 显式指定了值 10 ;the enum member Green is explicitly given the value 10;
  • 和枚举成员 Blue 被自动分配了一个大于在该成员前面有一个的成员的值。and the enum member Blue is automatically assigned the value one greater than the member that textually precedes it.

枚举成员的关联值不能直接或间接地使用其自己的关联枚举成员的值。The associated value of an enum member may not, directly or indirectly, use the value of its own associated enum member. 除了此循环限制之外,枚举成员初始值设定项可以随意引用其他枚举成员初始值设定项,而不考虑其文本位置。Other than this circularity restriction, enum member initializers may freely refer to other enum member initializers, regardless of their textual position. 在枚举成员初始值设定项中,其他枚举成员的值始终被视为具有其基础类型的类型,因此在引用其他枚举成员时不需要强制转换。Within an enum member initializer, values of other enum members are always treated as having the type of their underlying type, so that casts are not necessary when referring to other enum members.

示例The example

enum Circular
{
    A = B,
    B
}

导致编译时错误,因为和的声明 A B 是循环的。results in a compile-time error because the declarations of A and B are circular. A 依赖于 B 显式,并 B 依赖于 A 隐式。A depends on B explicitly, and B depends on A implicitly.

枚举成员的命名方式与类中的字段完全类似。Enum members are named and scoped in a manner exactly analogous to fields within classes. 枚举成员的作用域是其包含的枚举类型的正文。The scope of an enum member is the body of its containing enum type. 在该范围内,枚举成员可以通过其简单名称引用。Within that scope, enum members can be referred to by their simple name. 对于所有其他代码,枚举成员的名称必须用其枚举类型的名称进行限定。From all other code, the name of an enum member must be qualified with the name of its enum type. 枚举成员不具有任何已声明的可访问性-如果其包含枚举类型可访问,则枚举成员是可访问的。Enum members do not have any declared accessibility -- an enum member is accessible if its containing enum type is accessible.

System.Enum 类型The System.Enum type

类型 System.Enum 是所有枚举类型的抽象基类 (这是不同的,不同于枚举类型的基础类型) ,而从继承的成员 System.Enum 可用于任何枚举类型。The type System.Enum is the abstract base class of all enum types (this is distinct and different from the underlying type of the enum type), and the members inherited from System.Enum are available in any enum type. 装箱转换 (从任何枚举类型) 存在的 装箱 转换 System.Enum ,并 () 取消装箱转换 取消 装箱转换 System.Enum 为任何枚举类型。A boxing conversion (Boxing conversions) exists from any enum type to System.Enum, and an unboxing conversion (Unboxing conversions) exists from System.Enum to any enum type.

请注意, System.Enum 并不是 enum_typeNote that System.Enum is not itself an enum_type. 相反,它是派生所有 enum_typeclass_typeRather, it is a class_type from which all enum_type s are derived. 该类型 System.Enum 继承自类型 System.ValueType () ,后者又继承自类型 objectThe type System.Enum inherits from the type System.ValueType (The System.ValueType type), which, in turn, inherits from type object. 在运行时,type 的值 System.Enum 可以是或对 null 任何枚举类型的装箱值的引用。At run-time, a value of type System.Enum can be null or a reference to a boxed value of any enum type.

枚举值和操作Enum values and operations

每个枚举类型都定义了一个不同的类型;显式 枚举转换 () 需要在枚举类型和整型之间进行转换,或在两个枚举类型之间进行转换。Each enum type defines a distinct type; an explicit enumeration conversion (Explicit enumeration conversions) is required to convert between an enum type and an integral type, or between two enum types. 枚举类型可以采用的值集不受其枚举成员限制。The set of values that an enum type can take on is not limited by its enum members. 特别是,枚举的基础类型的任何值都可以转换为枚举类型,并且是该枚举类型的非重复有效值。In particular, any value of the underlying type of an enum can be cast to the enum type, and is a distinct valid value of that enum type.

枚举成员具有其包含枚举类型的类型 (除了其他枚举成员初始值设定项中:请参阅 枚举成员) 。Enum members have the type of their containing enum type (except within other enum member initializers: see Enum members). 使用关联值在枚举类型中声明的枚举成员的值 E v(E)vThe value of an enum member declared in enum type E with associated value v is (E)v.

可以在枚举类型的值上使用以下运算符: ==!= 、、 <> <=>=   (枚举比较运算符) 、binary +   (加法运算符) 、二进制 -   (减法运算符) 、、 (^ & |   枚举逻辑运算符) 、 (~   按位求补运算符) 以及 ++ (--   后缀增量和减量运算符以及前缀增量和减量运算符) 。The following operators can be used on values of enum types: ==, !=, <, >, <=, >= (Enumeration comparison operators), binary + (Addition operator), binary - (Subtraction operator), ^, &, | (Enumeration logical operators), ~ (Bitwise complement operator), ++ and -- (Postfix increment and decrement operators and Prefix increment and decrement operators).

每个枚举类型都自动派生自类 System.Enum (后者反过来派生自 System.ValueTypeobject) 。Every enum type automatically derives from the class System.Enum (which, in turn, derives from System.ValueType and object). 因此,此类的继承方法和属性可用于枚举类型的值。Thus, inherited methods and properties of this class can be used on values of an enum type.