列挙型(enum)
列挙型(enum)を使うと、一連の定数に名前を付けて、1つの型にまとめることができる。
列挙型を使うことで、マジックナンバーを避けることができる。
enumは英単語のenumerate(列挙する)を略したもので、日本ではイーナムと呼ぶ人が多い。英語圏ではイーナムまたはイニューム(injúːm)と呼ばれる。
基本的には相互排他的(同時に1つしか選択できない)な選択肢の集合となるが、2進数定数を使ってビットフラグとして扱うことで選択肢の組み合わせを表すことができる(後述)。
また、列挙型は値型である。
列挙型の定義
列挙型は以下のように定義する。
1 2 3 4 |
アクセス修飾子 enum 名前 { 列挙子リスト } |
1 2 3 4 5 6 7 |
public enum Season { Spring, //0 Summer, //1 Autumn, //2 Winter //3 } |
列挙子リストには、列挙したい名前(列挙子)をカンマで区切って記述する。
列挙子には整数値型の定数が割り振られている。
定数値の型はデフォルトではint型であり、列挙子を書いた順に0,1,2,・・・と割り振られる。
定数値の型を変更したい場合は、列挙型名につづけて:型名で指定する。型名には整数型しか使用できない。
また、定数値を独自に指定することもできる。
定数値を指定し、あとの定数値を指定しない場合、あとの定数値は指定した定数値に続いて自動で採番される。そのため、場合によっては定数値が競合しないよう注意が必要となる。
1 2 3 4 5 6 7 |
public enum Season : ushort //定数値の型を指定(整数値のみ指定可能) { Spring = 1, //定数値を指定 Summer, //自動的に2が採番される Autumn, //自動的に3が採番される Winter //自動的に4が採番される } |
列挙型のキャスト
列挙型の列挙子メンバーは、基となる整数値型と明示的にキャストすることができる。(暗黙的にはできない)
列挙型へのキャストは、以下の4行目のように、指定した定数に対応する列挙子メンバーがない場合も生成される。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Season season = Season.Autumn; Console.WriteLine((int)season); //2 Console.WriteLine((Season)3); //Winter Console.WriteLine((Season)4); //4(対応する列挙子がない) //Console.WriteLine(season == 2 //暗黙的な変換:コンパイルエラー public enum Season { Spring, Summer, Autumn, Winter } |
列挙型をswitch文で使う
列挙型は他の型を使うことができるほとんどの場所で使うことができるが、一般的にswitch文で使われることが多い。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
Season season = Season.Spring; switch (season) { case Season.Spring: Console.WriteLine("春です"); break; case Season.Summer: Console.WriteLine("夏です"); break; case Season.Autumn: Console.WriteLine("秋です"); break; case Season.Winter: Console.WriteLine("冬です"); break; } public enum Season { Spring, Summer, Autumn, Winter } |
1 |
春です |
列挙型で選択肢の組み合わせを表す(ビットフラグとしての列挙型)
2進数定数を使うことで、定数をビットフラグとして扱うことができる。
これを使うと、列挙型で複数の選択肢の組み合わせを表現することができる。
列挙型の宣言の前に、Flags属性を付けると、ToStringで列挙子の名前を得ることができる。Flags属性を付けない場合は定数となる。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[System.Flags] public enum Days { None = 0b_0000_0000, // 0 Monday = 0b_0000_0001, // 1 Tuesday = 0b_0000_0010, // 2 Wednesday = 0b_0000_0100,// 4 Thursday = 0b_0000_1000, // 8 Friday = 0b_0001_0000, // 16 Saturday = 0b_0010_0000, // 32 Sunday = 0b_0100_0000, // 64 Weekend = Saturday | Sunday } |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Days meetingDays = Days.Monday | Days.Wednesday | Days.Friday; Console.WriteLine(meetingDays);// Monday, Wednesday, Friday bool isMeetingOnTuesday = (meetingDays & Days.Tuesday) == Days.Tuesday; Console.WriteLine($"火曜日に会議があるか?: {isMeetingOnTuesday}"); bool isWeekend = (Days.Weekend & Days.Tuesday) == Days.Tuesday; Console.WriteLine($"火曜日は週末ですか?:{isWeekend}"); var a = (Days)37; //37 = 0b_0010_0101 Console.WriteLine(a);// Monday, Wednesday, Saturday Console.WriteLine(meetingDays.ToString()); //Monday, Wednesday, Friday(Flags属性がないと21と表示) |
コメント