System.Enum クラス

この記事では、この API のリファレンス ドキュメントへの補足的な解説を提供します。

列挙型は、基になる型が任意の整数型である名前付き定数のセットです。 基になる型が明示的に宣言されていない場合は、Int32が使用されます。 Enum は、.NET 内のすべての列挙型の基底クラスです。 列挙型は、C# のenumキーワード (keyword)、Visual Basic の Enum...End Enum コンストラクト、F type # のキーワード (keyword)によって定義されます。

Enumは、このクラスのインスタンスを比較し、インスタンスの値を文字列形式に変換し、数値の文字列形式をこのクラスのインスタンスに変換し、指定した列挙体と値のインスタンスを作成するメソッドを提供します。

列挙型をビット フィールドとして扱うこともできます。 詳細については、非排他的メンバーと Flags 属性セクションとFlagsAttributeを参照してください。

列挙型を作成する

通常、プログラミング言語では、名前付き定数とその値のセットで構成される列挙体を宣言するための構文が用意されています。 次の例は、列挙体を定義するために C#、F#、および Visual Basic で使用される構文を示しています。 ArrivalStatus.EarlyArrivalStatus.OnTime、およびArrivalStatus.Lateの3つのメンバーを持つArrivalStatusという名前の列挙体を作成します。 いずれの場合も、列挙型は明示的に継承 Enumされません。継承関係はコンパイラによって暗黙的に処理されます。

public enum ArrivalStatus { Unknown=-3, Late=-1, OnTime=0, Early=1 };
type ArrivalStatus =
    | Late = -1
    | OnTime = 0
    | Early = 1
Public Enum ArrivalStatus1 As Integer
    Late = -1
    OnTime = 0
    Early = 1
End Enum

警告

基になる型が非整数または Char. リフレクションを使用してこのような列挙型を作成できますが、結果の型を使用するメソッド呼び出しは信頼性が低く、追加の例外がスローされる場合もあります。

列挙型をインスタンス化する

他の値型をインスタンス化する場合と同様に、列挙型をインスタンス化するには、変数を宣言し、列挙型の定数の 1 つを割り当てます。 値がArrivalStatus.OnTimeであるArrivalStatusをインスタンス化する例を次に示します。

public class Example
{
   public static void Main()
   {
      ArrivalStatus status = ArrivalStatus.OnTime;
      Console.WriteLine("Arrival Status: {0} ({0:D})", status);
   }
}
// The example displays the following output:
//       Arrival Status: OnTime (0)
let status = ArrivalStatus.OnTime
printfn $"Arrival Status: {status} ({status:D})"
// The example displays the following output:
//       Arrival Status: OnTime (0)
Public Module Example1
    Public Sub Main()
        Dim status As ArrivalStatus1 = ArrivalStatus1.OnTime
        Console.WriteLine("Arrival Status: {0} ({0:D})", status)
    End Sub
End Module
' The example displays the following output:
'        Arrival Status: OnTime (0)

列挙値は、次の方法でインスタンス化することもできます。

  • 特定のプログラミング言語の機能を使用してキャスト (C# の場合) するか、変換する (Visual Basic の場合) ことで、整数値を列挙値に変換します。 次の例では、この方法でArrivalStatus.Early値を持つArrivalStatusオブジェクトを作成します。

    ArrivalStatus status2 = (ArrivalStatus)1;
    Console.WriteLine("Arrival Status: {0} ({0:D})", status2);
    // The example displays the following output:
    //       Arrival Status: Early (1)
    
    let status2 = enum<ArrivalStatus> 1
    printfn $"Arrival Status: {status2} ({status2:D})"
    // The example displays the following output:
    //       Arrival Status: Early (1)
    
    Dim status2 As ArrivalStatus2 = CType(1, ArrivalStatus2)
    Console.WriteLine("Arrival Status: {0} ({0:D})", status2)
    ' The example displays the following output:
    '       Arrival Status: Early (1)
    
  • 暗黙的なパラメーターなしのコンストラクターを呼び出すこと。 次の例に示すように、この場合、列挙インスタンスの基になる値は 0 です。 ただし、これは必ずしも列挙型の有効な定数の値であるとは限りません。

    ArrivalStatus status1 = new ArrivalStatus();
    Console.WriteLine("Arrival Status: {0} ({0:D})", status1);
    // The example displays the following output:
    //       Arrival Status: OnTime (0)
    
    let status1 = ArrivalStatus()
    printfn $"Arrival Status: {status1} ({status1:D})"
    // The example displays the following output:
    //       Arrival Status: OnTime (0)
    
    Dim status1 As New ArrivalStatus2()
    Console.WriteLine("Arrival Status: {0} ({0:D})", status1)
    ' The example displays the following output:
    '        Arrival Status: OnTime (0)
    
  • 列挙体の Parse 定数の名前を含む文字列を解析する or TryParse メソッドを呼び出すこと。 詳細については、「列挙値の解析」セクションを参照してください。

  • 整数値を ToObject 列挙型に変換するメソッドを呼び出すこと。 詳細については、「変換の実行」セクションを参照してください。

列挙のベスト プラクティス

列挙型を定義するときは、次のベスト プラクティスを使用することをお勧めします。

  • 値が 0 の列挙メンバーを定義していない場合は、None列挙定数を作成することを検討してください。 既定では、列挙体に使用されるメモリは、共通言語ランタイムによって 0 に初期化されます。 その結果、値が 0 である定数を定義しなかった場合、列挙体の作成時に無効な値が含まれます。

  • アプリケーションで表す必要がある明らかな既定のケースがある場合は、値が 0 の列挙定数を使用してそれを表すかどうかを検討してください。 既定のケースがない場合は、値が 0 の列挙定数を使用して、他の列挙定数で表されないケースを指定することを検討してください。

  • 将来使用するために予約されている列挙定数は指定しないでください。

  • 列挙定数を値として受け取るメソッドまたはプロパティを定義する場合は、値の検証を検討してください。 その理由は、その数値が列挙型で定義されていない場合でも、数値を列挙型にキャストできるためです。

定数がビット フィールドである列挙型の追加のベスト プラクティスについては、「非排他的メンバー」および「フラグ属性」セクションに記載されています

列挙型を使用して操作を実行する

列挙型を作成するときに、新しいメソッドを定義することはできません。 ただし、列挙型はクラスから静的メソッドとインスタンス メソッドの完全なセットを Enum 継承します。 次のセクションでは、列挙値を操作するときに一般的に使用される他のいくつかのメソッドに加えて、これらのメソッドのほとんどについて調査します。

変換を実行する

キャスト (C# および F# の場合) または変換 (Visual Basic の場合) を使用して、列挙型メンバーとその基になる型の間で変換できます。 F# では、 enum 関数も使用されます。 次の例では、キャスト演算子または変換演算子を使用して、整数から列挙値への変換と、列挙値から整数への変換の両方を実行します。

int value3 = 2;
ArrivalStatus status3 = (ArrivalStatus)value3;

int value4 = (int)status3;
let value3 = 2
let status3 = enum<ArrivalStatus> value3

let value4 = int status3
Dim value3 As Integer = 2
Dim status3 As ArrivalStatus2 = CType(value3, ArrivalStatus2)

Dim value4 As Integer = CInt(status3)

Enumクラスには、任意の整数型の値を列挙値に変換するToObjectメソッドも含まれています。 次の例では、ToObject(Type, Int32) 、メソッドを使用して、Int32ArrivalStatus値に変換します。 ToObjectObject型の値を返すため、キャスト演算子または変換演算子が、オブジェクトを列挙型にキャストするために必要になる場合があることに注意してください。

int number = -1;
ArrivalStatus arrived = (ArrivalStatus)ArrivalStatus.ToObject(typeof(ArrivalStatus), number);
let number = -1
let arrived = ArrivalStatus.ToObject(typeof<ArrivalStatus>, number) :?> ArrivalStatus
Dim number As Integer = -1
Dim arrived As ArrivalStatus2 = CType(ArrivalStatus2.ToObject(GetType(ArrivalStatus2), number), ArrivalStatus2)

整数を列挙値に変換するときに、実際には列挙型のメンバーではない値を割り当てることができます。 これを回避するには、変換を実行する前に、IsDefinedメソッドに整数を渡します。 次の例では、このメソッドを使用して、整数値の配列内の要素を値に ArrivalStatus 変換できるかどうかを判断します。

using System;

public class Example3
{
    public static void Main()
    {
        int[] values = { -3, -1, 0, 1, 5, Int32.MaxValue };
        foreach (var value in values)
        {
            ArrivalStatus status;
            if (Enum.IsDefined(typeof(ArrivalStatus), value))
                status = (ArrivalStatus)value;
            else
                status = ArrivalStatus.Unknown;
            Console.WriteLine("Converted {0:N0} to {1}", value, status);
        }
    }
}
// The example displays the following output:
//       Converted -3 to Unknown
//       Converted -1 to Late
//       Converted 0 to OnTime
//       Converted 1 to Early
//       Converted 5 to Unknown
//       Converted 2,147,483,647 to Unknown
open System

type ArrivalStatus =
    | Unknown = -3
    | Late = -1
    | OnTime = 0
    | Early = 1

let values = [ -3; -1; 0; 1; 5; Int32.MaxValue ]
for value in values do
    let status =
        if Enum.IsDefined(typeof<ArrivalStatus>, value) then
            enum value
        else
            ArrivalStatus.Unknown
    printfn $"Converted {value:N0} to {status}"
// The example displays the following output:
//       Converted -3 to Unknown
//       Converted -1 to Late
//       Converted 0 to OnTime
//       Converted 1 to Early
//       Converted 5 to Unknown
//       Converted 2,147,483,647 to Unknown
Public Enum ArrivalStatus4 As Integer
    Unknown = -3
    Late = -1
    OnTime = 0
    Early = 1
End Enum

Module Example4
    Public Sub Main()
        Dim values() As Integer = {-3, -1, 0, 1, 5, Int32.MaxValue}
        For Each value In values
            Dim status As ArrivalStatus4
            If [Enum].IsDefined(GetType(ArrivalStatus4), value) Then
                status = CType(value, ArrivalStatus4)
            Else
                status = ArrivalStatus4.Unknown
            End If
            Console.WriteLine("Converted {0:N0} to {1}", value, status)
        Next
    End Sub
End Module
' The example displays the following output:
'       Converted -3 to Unknown
'       Converted -1 to Late
'       Converted 0 to OnTime
'       Converted 1 to Early
'       Converted 5 to Unknown
'       Converted 2,147,483,647 to Unknown

Enumクラスには、列挙値から整数型への変換のためのIConvertibleインターフェイスの明示的なインターフェイス実装が用意されていますが、ToInt32などのConvertクラスのメソッドを使用して、これらの変換を実行することをお勧めします。 次の例は、GetUnderlyingTypeメソッドをConvert.ChangeTypeメソッドと共に使用して、列挙値を基になる型に変換する方法を示しています。 この例では、コンパイル時に列挙型の基になる型を認識する必要はありません。

ArrivalStatus status = ArrivalStatus.Early;
var number = Convert.ChangeType(status, Enum.GetUnderlyingType(typeof(ArrivalStatus)));
Console.WriteLine("Converted {0} to {1}", status, number);
// The example displays the following output:
//       Converted Early to 1
let status = ArrivalStatus.Early
let number = Convert.ChangeType(status, Enum.GetUnderlyingType typeof<ArrivalStatus>)
printfn $"Converted {status} to {number}"
// The example displays the following output:
//       Converted Early to 1
Dim status As ArrivalStatus5 = ArrivalStatus5.Early
Dim number = Convert.ChangeType(status, [Enum].GetUnderlyingType(GetType(ArrivalStatus5)))
Console.WriteLine("Converted {0} to {1}", status, number)
' The example displays the following output:
'       Converted Early to 1

列挙値の解析

ParseメソッドとTryParseメソッドを使用すると、列挙値の文字列形式をその値に変換できます。 文字列表現には、列挙定数の名前または基になる値を指定できます。 文字列を列挙型の基になる型の値に変換できる場合、解析メソッドは、特定の列挙体のメンバーではない数値の文字列表現を正常に変換することに注意してください。 これを回避するには、IsDefinedメソッドを呼び出して、解析メソッドの結果が有効な列挙値であることを確認します。 この例は、この方法を示し、Parse(Type, String)メソッドとEnum.TryParse<TEnum>(String, TEnum)メソッドの両方の呼び出しを示しています。 非ジェネリック解析メソッドは、(C# および F# で) キャストするか (Visual Basic では) 適切な列挙型に変換する必要があるオブジェクトを返します。

string number = "-1";
string name = "Early";

try
{
    ArrivalStatus status1 = (ArrivalStatus)Enum.Parse(typeof(ArrivalStatus), number);
    if (!(Enum.IsDefined(typeof(ArrivalStatus), status1)))
        status1 = ArrivalStatus.Unknown;
    Console.WriteLine("Converted '{0}' to {1}", number, status1);
}
catch (FormatException)
{
    Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus value.",
                      number);
}

ArrivalStatus status2;
if (Enum.TryParse<ArrivalStatus>(name, out status2))
{
    if (!(Enum.IsDefined(typeof(ArrivalStatus), status2)))
        status2 = ArrivalStatus.Unknown;
    Console.WriteLine("Converted '{0}' to {1}", name, status2);
}
else
{
    Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus value.",
                      number);
}
// The example displays the following output:
//       Converted '-1' to Late
//       Converted 'Early' to Early
let number = "-1"
let name = "Early"

try
    let status1 = Enum.Parse(typeof<ArrivalStatus>, number) :?> ArrivalStatus
    let status1 =
        if not (Enum.IsDefined(typeof<ArrivalStatus>, status1) ) then
            ArrivalStatus.Unknown
        else 
            status1
        
    printfn $"Converted '{number}' to {status1}"
with :? FormatException ->
    printfn $"Unable to convert '{number}' to an ArrivalStatus value."

match Enum.TryParse<ArrivalStatus> name with
| true, status2 ->
    let status2 = 
        if not (Enum.IsDefined(typeof<ArrivalStatus>, status2) ) then
            ArrivalStatus.Unknown
        else 
            status2
    printfn $"Converted '{name}' to {status2}"
| _ ->
    printfn $"Unable to convert '{number}' to an ArrivalStatus value."
// The example displays the following output:
//       Converted '-1' to Late
//       Converted 'Early' to Early
Dim number As String = "-1"
Dim name As String = "Early"
Dim invalid As String = "32"

Try
    Dim status1 As ArrivalStatus8 = CType([Enum].Parse(GetType(ArrivalStatus8), number), ArrivalStatus8)
    If Not [Enum].IsDefined(GetType(ArrivalStatus8), status1) Then status1 = ArrivalStatus8.Unknown
    Console.WriteLine("Converted '{0}' to {1}", number, status1)
Catch e As FormatException
    Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus8 value.",
                   number)
End Try

Dim status2 As ArrivalStatus8
If [Enum].TryParse(Of ArrivalStatus8)(name, status2) Then
    If Not [Enum].IsDefined(GetType(ArrivalStatus8), status2) Then status2 = ArrivalStatus8.Unknown
    Console.WriteLine("Converted '{0}' to {1}", name, status2)
Else
    Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus8 value.",
                   number)
End If
' The example displays the following output:
'       Converted '-1' to Late
'       Converted 'Early' to Early

列挙値の書式設定

静的 Format メソッドとインスタンス ToString メソッドのオーバーロードを呼び出すことで、列挙値を文字列形式に変換できます。 書式指定文字列を使用して、列挙値を文字列として表す正確な方法を制御できます。 詳細については、「列挙型書式指定文字列」を参照してください。 次の例では、サポートされている各列挙書式指定文字列 ("G" または "g"、"D"、"d"、"X"、"x"、"F"、"f") を使用して、ArrivalStatus列挙体のメンバーを文字列形式に変換します。

string[] formats = { "G", "F", "D", "X" };
ArrivalStatus status = ArrivalStatus.Late;
foreach (var fmt in formats)
    Console.WriteLine(status.ToString(fmt));

// The example displays the following output:
//       Late
//       Late
//       -1
//       FFFFFFFF
let formats = [ "G"; "F"; "D"; "X" ]
let status = ArrivalStatus.Late
for fmt in formats do
    printfn $"{status.ToString fmt}"

// The example displays the following output:
//       Late
//       Late
//       -1
//       FFFFFFFF
Dim formats() As String = {"G", "F", "D", "X"}
Dim status As ArrivalStatus6 = ArrivalStatus6.Late
For Each fmt As String In formats
    Console.WriteLine(status.ToString(fmt))
Next
' The example displays the following output:
'       Late
'       Late
'       -1
'       FFFFFFFF

列挙型メンバーを反復処理する

このEnum型は、(C# の場合)、(F# の場合) for..in 、または (Visual Basic の場合) コンストラクトを使用foreachしてコレクションのメンバーを反復処理できるようにする、またはIEnumerable<T>For Each インターフェイスを実装IEnumerableしません。 ただし、次の 2 つの方法のいずれかでメンバーを列挙できます。

  • このメソッドを GetNames 呼び出して、列挙メンバーの名前を含む文字列配列を取得できます。 次に、文字列配列の各要素について、メソッドを Parse 呼び出して、文字列を等価の列挙値に変換できます。 このアプローチの例を次に示します。

    string[] names = Enum.GetNames(typeof(ArrivalStatus));
    Console.WriteLine("Members of {0}:", typeof(ArrivalStatus).Name);
    Array.Sort(names);
    foreach (var name in names)
    {
        ArrivalStatus status = (ArrivalStatus)Enum.Parse(typeof(ArrivalStatus), name);
        Console.WriteLine("   {0} ({0:D})", status);
    }
    // The example displays the following output:
    //       Members of ArrivalStatus:
    //          Early (1)
    //          Late (-1)
    //          OnTime (0)
    //          Unknown (-3)
    
    let names = Enum.GetNames typeof<ArrivalStatus>
    printfn $"Members of {nameof ArrivalStatus}:"
    let names = Array.sort names
    for name in names do
        let status = Enum.Parse(typeof<ArrivalStatus>, name) :?> ArrivalStatus
        printfn $"   {status} ({status:D})"
    // The example displays the following output:
    //       Members of ArrivalStatus:
    //          Early (1)
    //          Late (-1)
    //          OnTime (0)
    //          Unknown (-3)
    
    Dim names() As String = [Enum].GetNames(GetType(ArrivalStatus7))
    Console.WriteLine("Members of {0}:", GetType(ArrivalStatus7).Name)
    Array.Sort(names)
    For Each name In names
        Dim status As ArrivalStatus7 = CType([Enum].Parse(GetType(ArrivalStatus7), name),
                                   ArrivalStatus7)
        Console.WriteLine("   {0} ({0:D})", status)
    Next
    ' The example displays the following output:
    '       Members of ArrivalStatus7:
    '          Early (1)
    '          Late (-1)
    '          OnTime (0)
    '          Unknown (-3)
    
  • このメソッドを GetValues 呼び出して、列挙体の基になる値を含む配列を取得できます。 次に、配列の各要素について、メソッドを ToObject 呼び出して整数を等価の列挙値に変換できます。 このアプローチの例を次に示します。

    var values = Enum.GetValues(typeof(ArrivalStatus));
    Console.WriteLine("Members of {0}:", typeof(ArrivalStatus).Name);
    foreach (ArrivalStatus status in values)
    {
        Console.WriteLine("   {0} ({0:D})", status);
    }
    // The example displays the following output:
    //       Members of ArrivalStatus:
    //          OnTime (0)
    //          Early (1)
    //          Unknown (-3)
    //          Late (-1)
    
    let values = Enum.GetValues typeof<ArrivalStatus>
    printfn $"Members of {nameof ArrivalStatus}:"
    for status in values do
        printfn $"   {status} ({status:D})"
    // The example displays the following output:
    //       Members of ArrivalStatus:
    //          OnTime (0)
    //          Early (1)
    //          Unknown (-3)
    //          Late (-1)
    
    Dim values = [Enum].GetValues(GetType(ArrivalStatus7))
    Console.WriteLine("Members of {0}:", GetType(ArrivalStatus7).Name)
    For Each value In values
        Dim status As ArrivalStatus7 = CType([Enum].ToObject(GetType(ArrivalStatus7), value),
                                         ArrivalStatus7)
        Console.WriteLine("   {0} ({0:D})", status)
    Next
    ' The example displays the following output:
    '       Members of ArrivalStatus7:
    '          OnTime (0)
    '          Early (1)
    '          Unknown (-3)
    '          Late (-1)
    

非排他的メンバーと Flags 属性

列挙型の一般的な用途の 1 つは、相互に排他的な値のセットを表すことです。 たとえば、ArrivalStatus 、インスタンスは、EarlyOnTime、またはLateの値を持つことができます。 インスタンスの値が複数の列挙定数を ArrivalStatus 反映しても意味がありません。

ただし別の場合、列挙オブジェクトの値には複数の列挙体メンバーを含めることができ、各メンバーは列挙値のビットフィールドを表します。 この FlagsAttribute 属性を使用して、列挙体がビット フィールドで構成されていることを示すことができます。 たとえば、Petsという名前の列挙体を使用して、家族のペットの種類を示すことができます。 次のように定義できます。

[Flags]
public enum Pets
{
    None = 0, Dog = 1, Cat = 2, Bird = 4, Rodent = 8,
    Reptile = 16, Other = 32
};
[<Flags>] 
type Pets =
    | None = 0
    | Dog = 1
    | Cat = 2
    | Bird = 4
    | Rodent = 8
    | Reptile = 16
    | Other = 32
<Flags> Public Enum Pets As Integer
   None = 0
   Dog = 1
   Cat = 2
   Bird = 4
   Rodent = 8
   Reptile = 16
   Other = 32
End Enum

Pets列挙体は、次の例に示すように使用できます。

Pets familyPets = Pets.Dog | Pets.Cat;
Console.WriteLine("Pets: {0:G} ({0:D})", familyPets);
// The example displays the following output:
//       Pets: Dog, Cat (3)
let familyPets = Pets.Dog ||| Pets.Cat
printfn $"Pets: {familyPets:G} ({familyPets:D})"
// The example displays the following output:
//       Pets: Dog, Cat (3)
Dim familyPets As Pets = Pets.Dog Or Pets.Cat
Console.WriteLine("Pets: {0:G} ({0:D})", familyPets)
' The example displays the following output:
'       Pets: Dog, Cat (3)

ビットごとの列挙型を定義し、属性を適用する場合は、次のベスト プラクティスを使用する FlagsAttribute 必要があります。

  • 数値に対してビットごとの演算 (AND、OR、EXCLUSIVE OR) を実行する場合にのみ、列挙体のFlagsAttributeカスタム属性を使用します。

  • 1、2、4、8 など、2 の累乗で列挙定数を定義します。 これは、結合された列挙定数内の個々のフラグが重複しないことを意味します。

  • 一般的に使用されるフラグの組み合わせに対して列挙定数を作成することを検討してください。 たとえば、列挙定数Read = 1Write = 2を含むファイル I/O 操作に使用する列挙体がある場合、ReadWriteを組み合わせたReadWrite = Read OR Write列挙定数を作成することを検討してください。 また、フラグを結合するために使用されるビットごとの OR 演算は、単純なタスクにとって不必要に高度な概念と見なされる場合があります。

  • フラグの位置が 1 に設定されている可能性があるため、負の数をフラグ列挙定数として定義する場合は注意が必要です。そのため、コードが混乱し、コーディング エラーが発生する可能性があります。

  • 数値でフラグが設定されているかどうかをテストする便利な方法は、次の例に示すように、HasFlagインスタンスメソッドを呼び出すことです。

    Pets familyPets = Pets.Dog | Pets.Cat;
    if (familyPets.HasFlag(Pets.Dog))
        Console.WriteLine("The family has a dog.");
    // The example displays the following output:
    //       The family has a dog.
    
    let familyPets = Pets.Dog ||| Pets.Cat
    if familyPets.HasFlag Pets.Dog then
        printfn "The family has a dog."
    // The example displays the following output:
    //       The family has a dog.
    
    Dim familyPets As Pets = Pets.Dog Or Pets.Cat
    If familyPets.HasFlag(Pets.Dog) Then
        Console.WriteLine("The family has a dog.")
    End If
    ' The example displays the following output:
    '       The family has a dog.
    

    これは、数値とフラグで列挙される定数の間でビットごとの AND 演算を実行することと同じです。この場合、数値のすべてのビットをフラグに対応しないゼロに設定し、その操作の結果がフラグ列挙定数と等しいかどうかをテストします。 このことを次の例で説明します。

    Pets familyPets = Pets.Dog | Pets.Cat;
    if ((familyPets & Pets.Dog) == Pets.Dog)
        Console.WriteLine("The family has a dog.");
    // The example displays the following output:
    //       The family has a dog.
    
    let familyPets = Pets.Dog ||| Pets.Cat
    if (familyPets &&& Pets.Dog) = Pets.Dog then
        printfn "The family has a dog."
    // The example displays the following output:
    //       The family has a dog.
    
    Dim familyPets As Pets = Pets.Dog Or Pets.Cat
    If familyPets And Pets.Dog = Pets.Dog Then
        Console.WriteLine("The family has a dog.")
    End If
    ' The example displays the following output:
    '       The family has a dog.
    
  • 値が 0 であるフラグ列挙定数の名前としてNoneを使用します。 ビットごとの and 演算では、結果が常に0であるため、None列挙定数を使用してフラグをテストすることはできません。 ただし、数値内のビットが設定されているかどうかを判断するために、数値とNoneに、数値と列挙定数の間でビットごとの比較ではなく論理演算を実行することができます。 このことを次の例で説明します。

    Pets familyPets = Pets.Dog | Pets.Cat;
    if (familyPets == Pets.None)
        Console.WriteLine("The family has no pets.");
    else
        Console.WriteLine("The family has pets.");
    // The example displays the following output:
    //       The family has pets.
    
    let familyPets = Pets.Dog ||| Pets.Cat
    if familyPets = Pets.None then
        printfn "The family has no pets."
    else
        printfn "The family has pets."
    // The example displays the following output:
    //       The family has pets.
    
    Dim familyPets As Pets = Pets.Dog Or Pets.Cat
    If familyPets = Pets.None Then
        Console.WriteLine("The family has no pets.")
    Else
        Console.WriteLine("The family has pets.")
    End If
    ' The example displays the following output:
    '       The family has pets.
    
  • 列挙値は、列挙体自体の状態をミラーするためだけに定義しないでください。 たとえば、列挙体の末尾だけをマークする列挙定数を定義しないでください。 列挙体の最後の値を決定する必要がある場合は、その値を明示的にチェックします。 また、範囲内のすべての値が有効な場合は、最初と最後の列挙定数の範囲チェックを実行できます。

列挙メソッドを追加する

列挙型は (C#)、(Visual Basic) Enum などのenum言語構造によって定義されるため、クラスから継承されたメソッド以外の列挙型のカスタム メソッドをEnum定義することはできません。 ただし、拡張メソッドを使用して、特定の列挙型に機能を追加できます。

次の例では、Grades 列挙型は学生が授業で受け取る成績評価を表わしています。 Passing という名前の拡張機能メソッドが Grades 型に追加されていて、この型の各インスタンスが合格点を表しているかどうかを自ら "認識" できるようになっています。 Extensionsクラスには、最小合格評価を定義する静的読み取り/書き込み変数も含まれています。 拡張メソッドの戻り値には、 Passing その変数の現在の値が反映されます。

using System;

// Define an enumeration to represent student grades.
public enum Grades { F = 0, D = 1, C = 2, B = 3, A = 4 };

// Define an extension method for the Grades enumeration.
public static class Extensions
{
    public static Grades minPassing = Grades.D;

    public static bool Passing(this Grades grade)
    {
        return grade >= minPassing;
    }
}

class Example8
{
    static void Main()
    {
        Grades g1 = Grades.D;
        Grades g2 = Grades.F;
        Console.WriteLine("{0} {1} a passing grade.", g1, g1.Passing() ? "is" : "is not");
        Console.WriteLine("{0} {1} a passing grade.", g2, g2.Passing() ? "is" : "is not");

        Extensions.minPassing = Grades.C;
        Console.WriteLine("\nRaising the bar!\n");
        Console.WriteLine("{0} {1} a passing grade.", g1, g1.Passing() ? "is" : "is not");
        Console.WriteLine("{0} {1} a passing grade.", g2, g2.Passing() ? "is" : "is not");
    }
}
// The exmaple displays the following output:
//       D is a passing grade.
//       F is not a passing grade.
//
//       Raising the bar!
//
//       D is not a passing grade.
//       F is not a passing grade.
open System
open System.Runtime.CompilerServices
// Define an enumeration to represent student grades.
type Grades =
    | F = 0
    | D = 1
    | C = 2
    | B = 3
    | A = 4

let mutable minPassing = Grades.D

// Define an extension method for the Grades enumeration.
[<Extension>]
type Extensions =
    [<Extension>]
    static member Passing(grade) = grade >= minPassing

let g1 = Grades.D
let g2 = Grades.F
printfn $"""{g1} {if g1.Passing() then "is" else "is not"} a passing grade."""
printfn $"""{g2} {if g2.Passing() then "is" else "is not"} a passing grade."""

minPassing <- Grades.C
printfn "\nRaising the bar!\n"
printfn $"""{g1} {if g1.Passing() then "is" else "is not"} a passing grade."""
printfn $"""{g2} {if g2.Passing() then "is" else "is not"} a passing grade."""
// The exmaple displays the following output:
//       D is a passing grade.
//       F is not a passing grade.
//
//       Raising the bar!
//
//       D is not a passing grade.
//       F is not a passing grade.
Imports System.Runtime.CompilerServices

' Define an enumeration to represent student grades.
Public Enum Grades As Integer
   F = 0
   D = 1
   C = 2
   B = 3
   A = 4
End Enum   

' Define an extension method for the Grades enumeration.
Public Module Extensions
  Public minPassing As Grades = Grades.D
 
  <Extension>
  Public Function Passing(grade As Grades) As Boolean
     Return grade >= minPassing
  End Function
End Module

Public Module Example
  Public Sub Main()
      Dim g1 As Grades = Grades.D
      Dim g2 As Grades = Grades.F
      Console.WriteLine("{0} {1} a passing grade.", 
                        g1, If(g1.Passing(), "is", "is not"))
      Console.WriteLine("{0} {1} a passing grade.", 
                        g2, If(g2.Passing(), "is", "is not"))
      Console.WriteLine()
      
      Extensions.minPassing = Grades.C
      Console.WriteLine("Raising the bar!")
      Console.WriteLine()
      Console.WriteLine("{0} {1} a passing grade.", 
                        g1, If(g1.Passing(), "is", "is not"))
      Console.WriteLine("{0} {1} a passing grade.", 
                        g2, If(g2.Passing(), "is", "is not"))
  End Sub
End Module
' The exmaple displays the following output:
'       D is a passing grade.
'       F is not a passing grade.
'       
'       Raising the bar!
'       
'       D is not a passing grade.
'       F is not a passing grade.

次の例では、列挙型を使用して名前付き値を表し、別の列挙型を使用して名前付きビット フィールドを表す方法を示します。

using System;

public class EnumTest {
    enum Days { Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday };
    enum BoilingPoints { Celsius = 100, Fahrenheit = 212 };
    [Flags]
    enum Colors { Red = 1, Green = 2, Blue = 4, Yellow = 8 };

    public static void Main() {

        Type weekdays = typeof(Days);
        Type boiling = typeof(BoilingPoints);

        Console.WriteLine("The days of the week, and their corresponding values in the Days Enum are:");

        foreach ( string s in Enum.GetNames(weekdays) )
            Console.WriteLine( "{0,-11}= {1}", s, Enum.Format( weekdays, Enum.Parse(weekdays, s), "d"));

        Console.WriteLine();
        Console.WriteLine("Enums can also be created which have values that represent some meaningful amount.");
        Console.WriteLine("The BoilingPoints Enum defines the following items, and corresponding values:");

        foreach ( string s in Enum.GetNames(boiling) )
            Console.WriteLine( "{0,-11}= {1}", s, Enum.Format(boiling, Enum.Parse(boiling, s), "d"));

        Colors myColors = Colors.Red | Colors.Blue | Colors.Yellow;
        Console.WriteLine();
        Console.WriteLine("myColors holds a combination of colors. Namely: {0}", myColors);
    }
}
open System

type Days =
    | Saturday = 0
    | Sunday = 1
    | Monday = 2
    | Tuesday = 3
    | Wednesday = 4
    | Thursday = 5
    | Friday = 6

type BoilingPoints =
    | Celsius = 100
    | Fahrenheit = 212

[<Flags>]
type Colors =
    | Red = 1
    | Green = 2
    | Blue = 4
    | Yellow = 8

let weekdays = typeof<Days>
let boiling = typeof<BoilingPoints>

printfn "The days of the week, and their corresponding values in the Days Enum are:"

for s in Enum.GetNames weekdays do
    printfn $"""{s,-11}= {Enum.Format(weekdays, Enum.Parse(weekdays, s), "d")}"""

printfn "\nEnums can also be created which have values that represent some meaningful amount."
printfn "The BoilingPoints Enum defines the following items, and corresponding values:"

for s in Enum.GetNames boiling do
    printfn $"""{s,-11}= {Enum.Format(boiling, Enum.Parse(boiling, s), "d")}"""

let myColors = Colors.Red ||| Colors.Blue ||| Colors.Yellow
printfn $"\nmyColors holds a combination of colors. Namely: {myColors}"
Public Class EnumTest
    Enum Days
        Saturday
        Sunday
        Monday
        Tuesday
        Wednesday
        Thursday
        Friday
    End Enum 
    
    Enum BoilingPoints
        Celsius = 100
        Fahrenheit = 212
    End Enum 
    
    <Flags()> _
    Enum Colors
        Red = 1
        Green = 2
        Blue = 4
        Yellow = 8
    End Enum 

    Public Shared Sub Main()
        Dim weekdays As Type = GetType(Days)
        Dim boiling As Type = GetType(BoilingPoints)

        Console.WriteLine("The days of the week, and their corresponding values in the Days Enum are:")

        Dim s As String
        For Each s In  [Enum].GetNames(weekdays)
            Console.WriteLine("{0,-11} = {1}", s, [Enum].Format(weekdays, [Enum].Parse(weekdays, s), "d"))
        
        Next s
        Console.WriteLine()
        Console.WriteLine("Enums can also be created which have values that represent some meaningful amount.")
        Console.WriteLine("The BoilingPoints Enum defines the following items, and corresponding values:")

        For Each s In  [Enum].GetNames(boiling)
            Console.WriteLine("{0,-11} = {1}", s, [Enum].Format(boiling, [Enum].Parse(boiling, s), "d"))
        Next s

        Dim myColors As Colors = Colors.Red Or Colors.Blue Or Colors.Yellow
        Console.WriteLine()
        Console.WriteLine("myColors holds a combination of colors. Namely: {0}", myColors)
    End Sub 
End Class