列挙型のFlags属性について

先日、プログラムを作っていたらC#の列挙型にはFlags属性というおもしろい属性が付けられることを知ったのでちょっと使ってみました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EnumTest {
     class Program {

          /// <summary>
          /// 体の部位を指定
          /// </summary>
          [Flags]
          enum 部位 {
               頭          = 1,
               右肩     = 2,
               左肩     = 4,
               右腕     = 8,
               左腕     = 16,
               おなか     = 32,
               腰          = 64,
               おしり     = 128,
               右足     = 256,
               左足     = 512,
          }

          /// <summary>
          /// 現在の行動を指定
          /// </summary>
          enum 行動 {
               停止 = 1,
               歩く = 2,
               走る = 4,
          }

          static void Main(string[] args) {
               ShowBuiEnum();
               ShowKoudouEnum();
               Console.ReadLine(); // ここで止める
          }


          static void ShowBuiEnum() {
               Console.WriteLine("【部位の列挙型テスト(Flags属性付与)】");
               Console.WriteLine("部位.おなか={0}", 部位.おなか);
               Console.WriteLine("部位.頭 | 部位.おなか | 部位.腰={0}", 部位.頭 | 部位.おなか | 部位.腰);
               Console.WriteLine("部位.右肩 | 部位.腰 | 部位.左足 | 部位.右腕={0}", 部位.右肩 | 部位.腰 | 部位.左足 | 部位.右腕);
               Console.WriteLine();
          }

          static void ShowKoudouEnum() {
               Console.WriteLine("【行動の列挙型テスト(Flags属性無し)】");
               Console.WriteLine("行動.走る={0}", 行動.走る);
               Console.WriteLine("行動.停止={0}", 行動.停止);
               Console.WriteLine("行動.歩く | 行動.停止={0}", 行動.歩く | 行動.停止);
               Console.WriteLine("行動.走る | 行動.歩く={0}", 行動.走る | 行動.歩く);
               Console.WriteLine();
          }
     }
}


(実行結果)


説明が前後してしまいましたが、Flags属性というのは「列挙型をビット フラグとして定義する」ための属性です。

Flags属性を付ける/付けないというのは、列挙型の各項目が完全独立かどうかで判断できます。

つまり列挙型の項目それぞれがお互いに影響しあうことがない場合、たとえば項目の重ね合わせに矛盾が生じないケースにFlags属性は利用できます。逆に赤信号と青信号のような同時に取りえない状態(排他状態)を表す場合にはFlags属性は付けません。