次の方法で共有


19 列挙型

19.1 全般

enum 型は、名前付き定数のセットを宣言する個別の値型 (§8.3) です。

例:

enum Color
{
    Red,
    Green,
    Blue
}

は、メンバー RedGreen、およびBlueを持つColorという名前の列挙型を宣言します。

end の例

19.2 列挙型宣言

列挙型宣言は、新しい列挙型を宣言します。 列挙型宣言はキーワード enumで始まり、列挙型の名前、アクセシビリティ、基になる型、およびメンバーを定義します。

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

enum_base
    : ':' integral_type
    | ':' integral_type_name
    ;

integral_type_name
    : type_name // Shall resolve to an integral type other than char
    ;

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

各列挙型には、列挙型の 基になる型 と呼ばれる対応する整数型があります。 この基になる型は、列挙体で定義されているすべての列挙子値を表すことができる必要があります。 enum_baseが存在する場合は、基になる型を明示的に宣言します。 基になる型は、char以外の integral 型 (§8.3.6) のいずれかになります。 基になる型は、 integral_type (§8.3.5) または integral_type_nameによって指定できます。 integral_type_nameは、using ディレクティブ (§14.5) を考慮するなど、type_name (§7.8.1) と同じ方法で解決されます。

: char 型は、キーワードまたは integral_type_nameを介して、基になる型として使用することはできません。 end note

基になる型を明示的に宣言しない列挙型宣言には、基になる型の intがあります。

: 例

enum Color : long
{
    Red,
    Green,
    Blue
}

は、基になる型の longを持つ列挙型を宣言します。

end の例

: 開発者は、例のように、基になる型の longを使用して、 long の範囲内にあるが intの範囲内にない値を使用できるようにするか、または将来のためにこのオプションを保持することを選択できます。 end note

: C# では、array_initializer内のコンマ (§17.7) で許可されるのと同様に、enum_bodyで末尾のコンマを使用できます。 end note

列挙型宣言には型パラメーター リストを含めることはできませんが、ジェネリック クラス宣言またはジェネリック構造体宣言内に入れ子になった列挙型はジェネリック列挙型宣言です。これは、包含型の型引数を指定して構築された型 (§8.4) を作成する必要があるためです。

19.3 列挙型修飾子

enum_declarationには、必要に応じて列挙修飾子のシーケンスを含めることができます。

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

列挙型宣言で同じ修飾子が複数回出現するのはコンパイル時エラーです。

列挙型宣言の修飾子は、クラス宣言の修飾子と同じ意味を持ちます (§15.2.2)。 ただし、列挙型宣言では、 abstractsealed、および static 修飾子は使用できません。 列挙型を抽象にすることはできず、派生を許可しません。

19.4 Enum メンバー

列挙型宣言の本体は、列挙型の名前付き定数である 0 個以上の列挙型メンバーを定義します。 同じ名前を持つ列挙型メンバーは 2 つありません。

enum_member_declarations
    : enum_member_declaration (',' enum_member_declaration)*
    ;
enum_member_declaration
    : attributes? identifier ('=' constant_expression)?
    ;

各列挙型メンバーには、関連付けられた定数値があります。 この値の型は、包含列挙型の基になる型です。 各列挙型メンバーの定数値は、列挙型の基になる型の範囲内でなければなりません。

: 例

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

定数値 -1-2、および -3 が基になる整数型の uintの範囲内にないため、コンパイル時エラーが発生します。

end の例

複数の列挙型メンバーは、同じ関連値を共有できます。

: 例

enum Color
{
    Red,
    Green,
    Blue,
    Max = Blue
}

は、2 つの列挙型メンバー (BlueMax) が同じ値を持つ列挙型を示しています。

end の例

列挙型メンバーの関連付けられた値は、暗黙的または明示的に割り当てられます。 列挙型メンバーの宣言に constant_expression 初期化子がある場合、列挙型の基になる型に暗黙的に変換される定数式の値は、列挙型メンバーの関連付けられた値です。 列挙型メンバーの宣言に初期化子がない場合、関連付けられた値は次のように暗黙的に設定されます。

  • 列挙型メンバーが列挙型で宣言された最初の列挙型メンバーである場合、関連付けられた値は 0 になります。
  • それ以外の場合、列挙型メンバーの関連付けられた値は、テキストの前にある列挙型メンバーの関連付けられた値を 1 ずつ増やすことによって取得されます。 この値の増加は、基になる型で表すことができる値の範囲内である必要があります。それ以外の場合は、コンパイル時エラーが発生します。

: 例

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 $"Red = {(int) c}";
            case Color.Green:
                return $"Green = {(int) c}";
            case Color.Blue:
                return $"Blue = {(int) c}";
            default:
                return "Invalid color";
      }
   }
}

は、列挙型メンバー名とそれに関連する値を出力します。 出力は次のようになります。

Red = 0
Green = 10
Blue = 11

次の理由から、

  • 列挙型メンバー Red には、値 0 が自動的に割り当てられます (初期化子がなく、最初の列挙型メンバーであるため)。
  • 列挙型メンバー Green には、 10値が明示的に与えられます。
  • 列挙型メンバー Blue は、その前のメンバーより 1 大きい値を自動的に割り当てます。

end の例

列挙型メンバーの関連付けられた値は、直接または間接的に、独自に関連付けられた列挙型メンバーの値を使用することはできません。 この循環性の制限以外に、列挙型メンバー初期化子は、テキストの位置に関係なく、他の列挙型メンバー初期化子を自由に参照できます。 列挙型メンバー初期化子内では、他の列挙型メンバーの値は常に基になる型の型を持つものとして扱われるので、他の列挙型メンバーを参照するときにキャストは必要ありません。

: 例

enum Circular
{
    A = B,
    B
}

ABの宣言が循環しているため、コンパイル時エラーが発生します。 A は明示的に B に依存し、 B は暗黙的に A に依存します。

end の例

列挙型メンバーは、クラス内のフィールドとまったく同じ方法で名前付けされ、スコープが設定されます。 列挙型メンバーのスコープは、その包含列挙型の本体です。 そのスコープ内では、列挙型メンバーは単純な名前で参照できます。 他のすべてのコードから、列挙型メンバーの名前は、その列挙型の名前で修飾する必要があります。 列挙型メンバーには、宣言されたアクセシビリティはありません。列挙型メンバーにアクセスできるのは、その列挙型が含まれている場合です。

19.5 System.Enum 型

System.Enum型は、すべての列挙型の抽象基底クラスであり (これは列挙型の基になる型とは異なります)、System.Enumから継承されたメンバーは任意の列挙型で使用できます。 任意の列挙型からSystem.Enumへのボックス化変換 (§10.2.9) が存在し、System.Enumから任意の列挙型へのボックス化解除変換 (§10.3.7) が存在します。

System.Enum自体がenum_typeではないことに注意してください。 むしろ、すべてのenum_typeが派生するclass_typeです。 型 System.Enum は型 System.ValueType (§8.3.2) から継承され、その型は型 objectから継承されます。 実行時に、 System.Enum 型の値を null することも、任意の列挙型のボックス化された値への参照にすることもできます。

19.6 列挙型の値と操作

各列挙型は、個別の型を定義します。列挙型と整数型の間、または 2 つの列挙型の間で変換するには、明示的な列挙変換 (§10.3.3) が必要です。 列挙型の値のセットは、基になる型の値のセットと同じであり、名前付き定数の値に制限されません。 列挙型の基になる型の任意の値を列挙型にキャストでき、その列挙型の個別の有効な値です。

列挙型メンバーには、含まれる列挙型の型があります (他の列挙型メンバー初期化子内を除く: §19.4 を参照)。 関連付けられた値を持つ列挙型Eで宣言された列挙型メンバーの値v(E)v

列挙型の値には、次の演算子を使用できます。

すべての列挙型は、クラス System.Enum から自動的に派生します (その結果、 System.ValueTypeobjectから派生します)。 したがって、このクラスの継承されたメソッドとプロパティは、列挙型の値で使用できます。