次の方法で共有


C# 列挙型

ヒント

ソフトウェアの開発は初めてですか? 最初に、 作業の開始 に関するチュートリアルから始めます。 プログラムで固定された選択肢のセットを表現する必要が出た場合、列挙型を使用することになります。

別の言語で経験がありますか? C# 列挙型は Java または C++ の列挙型と同様に機能し、ビット フラグとパターン マッチングのサポートが追加されています。 C# 固有のパターンの フラグswitch 式 セクションをスキミングします。

列挙型 (または列挙型) は、整数値でサポートされる名前付き定数のセットを定義します。 値がオプションの固定セット (曜日、HTTP 状態コード、ログ レベル、またはルート案内) のいずれかである必要がある場合は、列挙型を使用します。 列挙型を使用すると、コンパイラによって名前付き値が適用されるため、コードの読みやすさが向上し、単なる整数定数を使用するよりもエラーが発生しにくくなります。

列挙型を宣言する

enum キーワードの後に型名とそのメンバーが続く列挙型を定義します。

enum Season
{
    Spring,
    Summer,
    Autumn,
    Winter
}

既定では、基になる型は intされ、値は 0 から始まり、1 ずつインクリメントされます。 Season.Spring0Season.Summer1などです。

基になる型と明示的な値を指定する

別の整数型を選択し、明示的な値を割り当てて数値表現を制御できます。

enum HttpStatus : ushort
{
    OK = 200,
    NotFound = 404,
    InternalServerError = 500
}

HTTP 状態コードやプロトコル識別子など、数値に外部の意味がある場合は、明示的な値を使用します。 基になる型には、を除く任意のcharを指定できます。 byteshortushortintuintlong、またはulongを使用します。

switch 式で列挙型を使用する

列挙型は、 switch 式とパターン マッチングで自然に動作します。 すべてのメンバーを処理しないと、コンパイラから警告が表示されます。これは、後で新しい値を追加するときにバグを防ぐのに役立ちます。

static string DescribeSeason(Season season) => season switch
{
    Season.Spring => "Flowers bloom and temperatures rise.",
    Season.Summer => "Long days and warm weather.",
    Season.Autumn => "Leaves change color and fall.",
    Season.Winter => "Short days and cold temperatures.",
    _ => throw new ArgumentOutOfRangeException(nameof(season))
};
var today = Season.Autumn;
Console.WriteLine(DescribeSeason(today));

破棄パターン (_) は、明示的にリストされていない値を処理します。 パターン マッチング は、図形または条件に対して値をテストする C# 機能です。 この例では、各 case は列挙型が特定のメンバーと一致するかどうかを確認します。 Switch 式は、いくつかのパターン マッチング フォームの 1 つです。 パターン マッチングの詳細については、「パターン マッチング」を参照してください。

ビット フラグ

列挙型が 1 つの選択肢ではなく選択肢の組み合わせを表す場合は、各メンバーを 2 の累乗として定義し、 FlagsAttributeを適用します。

[Flags]
enum FileAccess
{
    None = 0,
    Read = 1,
    Write = 2,
    Execute = 4,
    ReadWrite = Read | Write,
    All = Read | Write | Execute
}

|演算子を使用して値を結合し、HasFlagを使用して個々のフラグをテストします。

var permissions = FileAccess.Read | FileAccess.Write;

Console.WriteLine(permissions);                          // ReadWrite
Console.WriteLine(permissions.HasFlag(FileAccess.Read)); // True
Console.WriteLine(permissions.HasFlag(FileAccess.Execute)); // False

[Flags]属性は、ToString()にも影響します。 結合された値は、生の数値ではなくコンマ区切りの名前 ( Read, Write など) として表示されます。 詳細については、System.FlagsAttributeを参照してください。

列挙型と整数の間で変換する

明示的キャストは、列挙型とその基となる整数型の間での変換を行います。

var status = HttpStatus.NotFound;
ushort code = (ushort)status;
Console.WriteLine($"Status: {status} ({code})"); // Status: NotFound (404)

var fromCode = (HttpStatus)200;
Console.WriteLine(fromCode); // OK

列挙型に整数をキャストしても、値が定義されたメンバーと一致するかどうかは検証されません。 外部ソースからの数値入力を受け入れる場合は、 Enum.IsDefined を使用して有効性を確認します。

文字列を解析して値を反復処理する

Enum基本クラスには、文字列を解析し、定義されたすべての値を反復処理するためのメソッドが用意されています。

// Parse a string to an enum value:
var parsed = Enum.Parse<Season>("Winter");
Console.WriteLine(parsed); // Winter

// Try to parse safely. It returns false only when the input can't be parsed. Call Enum.IsDefined to validate named members:
if (Enum.TryParse<Season>("Monsoon", out var unknown))
{
    Console.WriteLine(unknown);
}
else
{
    Console.WriteLine("'Monsoon' is not a valid Season"); // 'Monsoon' is not a valid Season
}

// Iterate over all values in an enum:
foreach (var season in Enum.GetValues<Season>())
{
    Console.WriteLine($"{season} = {(int)season}");
}
// Spring = 0
// Summer = 1
// Autumn = 2
// Winter = 3

入力が無効な場合は、Enum.TryParse<TEnum>(String, Boolean, TEnum)の代わりにEnum.Parse<TEnum>(String)を使用します。 例外をスローするのではなく、 false を返します。

こちらも参照ください