ホームに戻る
出典 :
列挙型 - C# リファレンス | Microsoft Learn FlagsAttribute クラス (System) | Microsoft Learn Enum.HasFlag(Enum) メソッド (System) | Microsoft Learn Enum.GetName メソッド (System) | Microsoft Learn 【C#入門】enum(列挙型)の使い方総まとめ(文字列/int/foreach) | 侍エンジニアブログ 【C#入門】enumの値と名前をforeachで列挙する(GetValues/GetNames) | 侍エンジニアブログ 【C#入門】enumの値を文字列に変換する方法(属性の定義も解説) | 侍エンジニアブログ C#のenumでビット演算をする - Qiita
関連 :
[C#]文字列リテラル [C#]組み込み型一覧
目次 :

列挙型をビットフィールド(フラグセット)として用いる

[Flags]属性を付与することで、列挙型をフラグとして用いることができるようになる。
その際、各列挙子は 0 または2のべき乗でなければならない

(コード例)
using System; class Example { // Flags 属性無しの列挙体定義 enum SingleHue : short { None = 0, Black = 1, Red = 2, Green = 4, Blue = 8, }; // Flags 属性つきの列挙体定義 [Flags] enum MultiHue : short { None = 0, Black = 1, //< 2 ^ 0 Red = 2, //< 2 ^ 1 Green = 4, //< 2 ^ 2 Blue = 8, //< 2 ^ 3 }; static void Main( ) { Console.WriteLine( "SingleHue :" ); for(int val = 0; val <= 16; val++ ) Console.WriteLine( $"{val} - {( (SingleHue)val ).ToString()}" ); Console.WriteLine( "" ); Console.WriteLine( "MultiHue :" ); for( int val = 0; val <= 16; val++ ) Console.WriteLine( $"{val} - {( (MultiHue)val ).ToString()}" ); } }
(出力結果)
SingleHue : 0 - None 1 - Black 2 - Red 3 - 3 4 - Green 5 - 5 6 - 6 7 - 7 8 - Blue 9 - 9 10 - 10 11 - 11 12 - 12 13 - 13 14 - 14 15 - 15 16 - 16 MultiHue : 0 - None 1 - Black 2 - Red 3 - Black, Red //< 1 + 2 4 - Green 5 - Black, Green //< 1 + 4 6 - Red, Green //< 2 + 4 7 - Black, Red, Green //< 1 + 2 + 4 8 - Blue 9 - Black, Blue //< 1 + 8 10 - Red, Blue //< 2 + 8 11 - Black, Red, Blue //< 1 + 2 + 8 12 - Green, Blue //< 4 + 8 13 - Black, Green, Blue //< 1 + 4 + 8 14 - Red, Green, Blue //< 2 + 4 + 8 15 - Black, Red, Green, Blue //< 1 + 2 + 4 + 8 16 - 16
Flags 属性の無い SingleHue は、定義されたシンボルのみが文字列として出力されているが、
Flags 属性を付与した MultiHue は、セットされたビットに対応するシンボルすべてを出力している。

Enumに対するビット演算

// ビット論理和 MultiHue color = MultiHue.Black | MultiHue.Green; //< Black, Green // ビットセット color |= MultiHue.Red; //< Black, Red, Green // ビットクリア color &= ~MultiHue.Green; //< Black, Red // フラグの確認 (HasFlag() メソッド) if ( color.HasFlag(MultiHue.Black) ) { Console.WriteLine ("Black included"); } // フラグの確認 (AND演算・上記と等価) if ( color & MultiHue.Black ) { Console.WriteLine ("Black included"); }
特定のビット(フラグ)がセットされていることはAND演算、または HasFlag() メソッドにより確認できる。
但し、HasFlag() は値型(enum)を参照型(Enum)にボックス化するため、パフォーマンスへの影響が発生する。

列挙子と文字列リテラル

列挙子に対して ToString() を実行すると、基となる値ではなくラベルが取得できる。
このため列挙子を複合文字列、または文字列補完に含めた場合はラベルが埋め込まれる。
( ToString() を暗黙的にコールしているため。ToString() をオーバーロードすることで異なる出力を得ることもできる。)
using System; public class Sample { // 列挙型の定義 enum Colors { Red, Green, Blue, Yellow }; public static void Main() { Colors c1 = Colors.Blue; Colors c2 = Colors.Red; // 複合文字列 Console.WriteLine( "c1 は {0} です。", c1 ); // 文字列補完 Console.WriteLine( $"c2 は {c2} です。" ); } } // 出力結果 : // c1 は Blue です。 // c2 は Red です。

列挙子の要素名(ラベル)の取得 : GetName() / ToString()

string? Enum.GetName(Type enumType, object value)

値 value が列挙型 enumType に含まれる場合に、対応する列挙子のラベルを文字列形式で返却する。
value が enumType に含まれない場合は null を返す。
using System; public class Sample { // 列挙型の定義 enum Colors { Red, Green, Blue, Yellow }; public static void Main() { // 値 3 に相当するラベルを取得、画面に表示 // ⇒ lbl = "Yellow" となる string lbl = Enum.GetName( typeof( Colors ), 3 ); Console.WriteLine( $"列挙体 Colors において 3 に相当するラベルは {lbl} です。" ); } } // 出力結果 : // 列挙体 Colors において 3 に相当するラベルは Yellow です。

注意が必要な点

value で指定された値が複数のメンバに該当する(複数のメンバが同じ値を持つ)場合、GetName() はそのうちのいずれかを返すが、いずれのメンバが返されるかは不定である。
(尤も、値が重複するような用途はそもそも適切ではない。)

string? Enum.GetName<TEnum>(TEnum value)

列挙値 value のラベルを文字列形式で返却する。
using System; public class Sample { // 列挙型の定義 enum Colors { Red, Green, Blue, Yellow }; public static void Main() { // Colors.Green のラベルを取得、画面に表示 // ⇒ "Green" が表示される Colors col = Colors.Green; string lbl = Enum.GetName( col ); Console.WriteLine( lbl ); } } // 出力結果 : // Green

string ToString()

列挙値のラベルを文字列形式で返却する。
using System; public class Sample { // 列挙型の定義 enum Colors { Red, Green, Blue, Yellow }; public static void Main() { // Colors.Green のラベルを取得、画面に表示 // ⇒ "Green" が表示される Colors col = Colors.Green; string lbl = col.ToString(); Console.WriteLine( lbl ); } } // 出力結果 : // Green

Enum.GetName() との差異

Enum.GetName() は引数で指定された値が列挙型に含まれない場合に null を返すが、ToString() は String.Empty を返す。
null を考慮する必要が無いため、ToString() はより簡便に用いることができる。

値または要素名(ラベル)の集合の取得 : GetValues() / GetNames()

Enum の静的メソッド GetValues() 、GetNames() を用いることで、引数に指定した列挙型のすべての値、またはすべてのラベルを集合として取得することができる。
これにより、列挙型に対する繰り返し処理( foreach )を行うことができる。尚、引数には列挙型の型情報( typeof(...) )を与える。

GetValues() : 値の抽出

コード :
using System; namespace Sample { // 列挙型の定義 enum E_Name { Himurock = 0, Kikkawa = 1, Hotei = 2, } // サンプルクラス class Sample { static void Main() { // 列挙型 E_Name に対する foreach // Enum.GetValues() で値の集合を抽出する foreach (E_Name val in Enum.GetValues(typeof(E_Name))) { // Enum.GetName() で値から名前を得る string name = Enum.GetName(typeof(E_Name), val); Console.WriteLine($"{name} : {(int)val}"); } } } }
実行結果 :
Himurock : 0 Kikkawa : 1 Hotei : 2
Enum.GetValues() および Enum.GetName() の引数に typeof(E_Name) を指定している点に注意。
これは後述の Enum.GetNames() も同様である。

GetNames() : ラベルの抽出

コード :
using System; namespace Sample { // 列挙型の定義 enum E_Name { Himurock = 0, Kikkawa = 1, Hotei = 2, } // サンプルクラス class Sample { static void Main() { // 列挙型 E_Name に対する foreach // Enum.GetNames() でラベルの集合を抽出する foreach (string name in Enum.GetNames(typeof(E_Name))) { Console.WriteLine(name); } } } }
実行結果 :
Himurock Kikkawa Hotei
Enum.GetNames() の戻り値は string[] 。

指定した値が列挙体に含まれるかを確認する : IsDefined()

指定した値が列挙型に含まれる場合に true 、そうでない場合に false を返す。
int unknown = -1; if (Enum.IsDefined(typeof(Colors), unknown)) { // unknown(-1) が Colors のメンバに含まれていればここを通る }

指定した値を列挙オブジェクトに変換する : Parse() / TryParse()

Parse() は指定した値が列挙体に変換可能( IsDefined() == true )ならば変換を実行、変換できない場合は例外を発する。
TryParse() は変換が可能であれば変換を行うとともに true を返し、変換できなければ false を返す。
いずれも複数のオーバーロードが存在するが、ここでは代表的なもののみを紹介する。
// MultiHue に Black が含まれていれば result1 は MultiHue.Black と等価、 // そうでなければ例外 object result1 = Enum.Parse(typeof(MultiHue), "Black"); // MultiHue に Green が含まれていれば result2 は MultiHue.Green 、 // そうでなければ例外 MultiHue result2 = Enum.Parse<MultiHue>("Green"); // MultiHue に Blue が含まれていれば result3 は MultiHue.Blue と等価、 // そうでなければ null となる bool succeed = Enum.TryParse(typeof(MultiHue), "Blue", out object? result3); // MultiHue に Red が含まれていれば result4 は MultiHue.Red 、 // そうでなければ MultiHue の既定値となる bool succeed = Enum.TryParse<MultiHue>("Red", out MultiHue result4);
変換成功時
(戻り値)
変換失敗時
Parse() object 型 ArgumentException
Parse<TEnum>() TEnum 型
out引数の型 変換成功時 変換失敗時
out引数の値 戻り値 out引数の値 戻り値
TryParse() object 型 対応する列挙オブジェクト true null false
TryParse<TEnum>() TEnum 型 TEnum の既定値