C#の列挙型:定義・使用法・ビットフラグ・ベストプラクティス完全ガイド
列挙型(enum)は、名前付き整数定数のセットです。列挙型はenumキーワードで宣言します。
C#の列挙型は値型データです。つまり、列挙型は独自の値を持ち、継承することも、継承されることもできません。
enum変数の宣言
列挙型を宣言する一般的な構文は以下の通りです。
enum <enum_name> { enumeration_list };
ここで、
enum_name- 列挙型の型名を指定enumeration_list- 識別子のカンマ区切りリスト
列挙リスト内の各シンボルは、直前のシンボルより1大きい整数値を表します。デフォルトでは、最初の列挙シンボルの値は0です。
基本的なenum宣言例
enum Days { Sun, Mon, Tue, Wed, Thu, Fri, Sat }
この例では:Sun=0, Mon=1, Tue=2, Wed=3, Thu=4, Fri=5, Sat=6となります。
明示的な値の割り当て
列挙子に明示的に値を割り当てることもできます。
enum HttpStatusCode {
OK = 200,
Created = 201,
BadRequest = 400,
Unauthorized = 401,
NotFound = 404,
InternalServerError = 500
}
enumの使用例
using System;
namespace EnumApplication {
class EnumProgram {
enum Days { Sun, Mon, Tue, Wed, Thu, Fri, Sat };
static void Main(string[] args) {
int weekDayStart = (int)Days.Mon;
int weekDayEnd = (int)Days.Fri;
Console.WriteLine("Monday: {0}", weekDayStart); // 1
Console.WriteLine("Friday: {0}", weekDayEnd); // 5
Console.ReadKey();
}
}
}
実行結果:
Monday: 1
Friday: 5
基底型の指定
デフォルトではintですが、他の整数型(byte, sbyte, short, ushort, uint, long, ulong)を基底型として指定できます。
enum Priority : byte {
Low = 1,
Medium = 2,
High = 3,
Critical = 4
}
Enumクラスの主要メソッド
| メソッド | 説明 |
|---|---|
Enum.GetNames(typeof(T)) | 定数名の配列を取得 |
Enum.GetValues(typeof(T)) | 定数値の配列を取得 |
Enum.IsDefined(typeof(T), value) | 指定値が定義されているか判定 |
Enum.Parse(typeof(T), "Name") | 文字列から列挙値に変換 |
Enum.TryParse(typeof(T), "Name", out result) | 安全に文字列から変換(C# 4.0以降) |
Enum.GetName(typeof(T), value) | 値から定数名を取得 |
Enum.HasFlag(flags) | フラグが含まれるか判定(Flags属性時) |
メソッド使用例
enum Colors { Red, Green, Blue }
// 名前の取得
string[] names = Enum.GetNames(typeof(Colors));
// ["Red", "Green", "Blue"]
// 値の取得
Array values = Enum.GetValues(typeof(Colors));
// [0, 1, 2]
// 文字列から変換
Colors color = (Colors)Enum.Parse(typeof(Colors), "Green");
// または(型安全)
Enum.TryParse("Green", out Colors color2);
// 判定
bool defined = Enum.IsDefined(typeof(Colors), 99); // false
フラグ属性([Flags])とビット演算
[Flags]属性を付けると、列挙型をビットフィールドとして扱えます。値は2の累乗にするのが慣例です。
[Flags]
enum FileAccess {
None = 0,
Read = 1, // 2^0
Write = 2, // 2^1
Execute = 4, // 2^2
Delete = 8, // 2^3
All = Read | Write | Execute | Delete // 15
}
フラグ列挙型の操作例
FileAccess access = FileAccess.Read | FileAccess.Write; // 3
// フラグのチェック
bool canRead = (access & FileAccess.Read) != 0; // true
bool canExecute = access.HasFlag(FileAccess.Execute); // false (C# 4.0+)
// フラグの追加/削除
access |= FileAccess.Execute; // 追加
access &= ~FileAccess.Write; // 削除
// 全フラグ列挙
foreach (FileAccess flag in Enum.GetValues(typeof(FileAccess))) {
if (access.HasFlag(flag) && flag != FileAccess.None) {
Console.WriteLine(flag);
}
}
switch式でのパターンマッチング(C# 8.0以降)
string GetDayType(Days day) => day switch {
Days.Sat or Days.Sun => "Weekend",
Days.Mon => "Monday blues",
Days.Fri => "TGIF!",
_ => "Weekday"
};
ベストプラクティス
- 列挙型名は単数形(
DayではなくDaysも可、チームで統一) - デフォルト値(0)には意味のある名前を付ける(
None,Unknown,Defaultなど) - フラグ列挙型には必ず
[Flags]属性を付け、値を2の累乗にする - 公開APIでは基底型を明示的に指定する(将来の拡張性のため)
Enum.IsDefinedやEnum.TryParseで未定義値を検知・防御する- マジックナンバーの代わりに列挙型を使用して可読性を高める
よくある落とし穴
- キャストで任意の整数値を代入できてしまう(
Days d = (Days)999;はコンパイルエラーにならない) Enum.HasFlagはボックス化が発生するため、高頻度呼び出しではビット演算(&)の方が高速- 既定値(0)が有効な状態を表す場合、未初期化状態と区別できない問題に注意
C言語
- C# Hello World – 初めてのC#アプリケーション構築
- C# キーワードと識別子:ルール、一覧、ベストプラクティス完全ガイド
- C# 変数とプリミティブデータ型:完全マスターガイド
- C#演算子完全ガイド:C#における演算子の包括的解説
- C# ビット演算子とビットシフト演算子をマスターする:包括的ガイド
- C# 入出力の基礎:ユーザー入力と出力の基本をマスター
- C# の式、文、ブロック:実践例で徹底理解
- C# コメントをマスターする:種類、ベストプラクティス、XML ドキュメント
- C# switch 文をマスターする:構文、例、ベストプラクティス
- C# 三項演算子:条件式を簡潔に書くためのガイド
- C# break 文:使い方とタイミングを徹底解説