[C#] 列挙型(enum)をビット演算に対応させる

通常の列挙型(enum)の値は当然複数の値をもたせることはできません。ですが Flags 属性を持たせることで、ビット演算によるフラグ管理の対象にできます。

Flags 属性付与プラス、列挙型の値を2の冪乗の形で定義することで、ビットフラグに対応させることが可能になります。

列挙型(enum)の定義

以下のような列挙型 Colors を定義します。内部の値は2の冪乗で定義します。単純に2nの値を定義しても良いですし、わかりにくければ16進数やビットシフトで値を定義しても良いです。

[Flags]
public enum Colors
{
    Black = 1,      // 0x0001
    Red   = 2,      // 0x0002 or 1 << 1,
    Green = 4,      // 0x0004 or 1 << 2,
    Blue  = 8,      // 0x0008 or 1 << 3,
    White = 16,     // 0x0010 or 1 << 4,
}

ビットフラグの使い方

列挙型の値同士で OR演算(A | B) をとることで複数の値のフラグを保持させる事ができます。保持した値のフラグ情報に値が含まれるかどうかは、Enum.HasFlagメソッドを使います。

Flag属性を付与していると、ToStringメソッドの戻り値が、保持しているフラグに対応する値の文字列のカンマ区切りになります。

サンプルコード

// 内部的な整数値は 17 (0x0011)
Colors blackOrWhite = Colors.Black | Colors.White;

// true, false
Console.WriteLine($"{blackOrWhite.HasFlag(Colors.Black)}");
Console.WriteLine($"{blackOrWhite.HasFlag(Colors.Red)}");

// Black, White
Console.WriteLine($"{blackOrWhite.ToString()}");