列舉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 且成員 RedGreenBlue的列舉類型。declares an enum type named Color with members Red, Green, and Blue.

列舉宣告Enum declarations

Enum 宣告會宣告新的列舉類型。An enum declaration declares a new enum type. Enum 宣告的開頭為關鍵字 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. Enum 宣告可以明確宣告 bytesbyteshortushortintuintlongulong的基礎類型。An 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. 未明確宣告基礎類型的列舉宣告具有 int的基礎類型。An enum declaration that does not explicitly declare an underlying type has an underlying type of int.

範例The example

enum Color: long
{
    Red,
    Green,
    Blue
}

宣告具有 long基礎類型的列舉。declares 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 修飾詞Enum modifiers

Enum_declaration可以選擇性地包含一連串的 enum 修飾詞: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.

Enum 宣告的修飾詞與類別宣告(類別修飾詞)的修飾詞具有相同的意義。The modifiers of an enum declaration have the same meaning as those of a class declaration (Class modifiers). 不過,請注意,在列舉宣告中不允許 abstractsealed 修飾詞。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 的常數值不在基礎整數類型 uint的範圍內。results 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:

  • enum 成員 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
}

會導致編譯時期錯誤,因為 AB 的宣告是迴圈的。results in a compile-time error because the declarations of A and B are circular. A 取決於明確 B,而 B 則會隱含地相依于 AA 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.string 類型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_types are derived. 類型 System.Enum 繼承自類型 System.ValueType (system.string類型),而後者又繼承自類型 objectThe type System.Enum inherits from the type System.ValueType (The System.ValueType type), which, in turn, inherits from type object. 在執行時間,可以 null 類型 System.Enum 的值,或任何列舉類型之已裝箱值的參考。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 成員具有其包含列舉類型的類型(但在其他列舉成員初始化運算式內除外):請參閱列舉成員)。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 + (加法運算子)、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.