本文へスキップ
BecomeCoder

C#オブジェクト指向コース · 第2章 型を表現する · レッスン17

Flags enum とビット演算

ブラウザで完結

導入

権限(読み取り・書き込み・実行)のように、複数の選択肢を同時に持たせたいことがあります。[Flags]属性を付けたenumビット演算を使うと、1つの値で「読み取り+書き込み」のような組み合わせを表せます。仕組みの土台であるビット演算もここで押さえます。

図解

flowchart LR
    R["Read  = 1 (0001)"] --> OR["| で組み合わせ"]
    W["Write = 2 (0010)"] --> OR
    OR --> C["Read|Write = 3 (0011)"]
    C -->|HasFlag / &| Q["その権限を含む?"]

サンプル

// | (OR) で権限を組み合わせる
Permission p = Permission.Read | Permission.Write;
Console.WriteLine(p);                            // Read, Write([Flags]なので名前で表示)
Console.WriteLine(p.HasFlag(Permission.Write));  // True(その権限を含むか)
Console.WriteLine(p.HasFlag(Permission.Exec));   // False

// ビット演算そのもの
Console.WriteLine(1 << 2);   // 4  ← 左シフト(2のべき乗を作る)
Console.WriteLine(6 & 3);    // 2  ← ビットAND(共通して立つビット)
Console.WriteLine(4 | 1);    // 5  ← ビットOR(どちらかが立つビット)

// [Flags] は「組み合わせられる列挙型」。各値を 2 のべき乗にするのがコツ
[Flags]
enum Permission
{
    None  = 0,
    Read  = 1,   // 0001
    Write = 2,   // 0010
    Exec  = 4,   // 0100
}
  • [Flags]を付け、各メンバーを1, 2, 4, 8...(2のべき乗)にすると組み合わせて使える
  • |(OR)で組み合わせ、HasFlagまたは&(AND)で「その権限を含むか」を判定
  • ビット演算:<<(左シフト)・&(AND)・|(OR)・^(XOR)が基本

演習

Perm p = Perm.Read | Perm.Exec;

// TODO: p が Exec を含むかどうかを出力してください(True)
___

[Flags]
enum Perm { None = 0, Read = 1, Write = 2, Exec = 4 }
  • 期待される出力: True
ヒント1を見る

p.HasFlag(Perm.Exec)で判定できます

ヒント2を見る

Console.WriteLine(p.HasFlag(Perm.Exec));

まとめ

  • [Flags] enumは各値を2のべき乗にして組み合わせを表す
  • |で組み合わせ、HasFlag/&で含有判定
  • 土台のビット演算<< & | ^も覚えておく

次回: 複数の値を軽くまとめる「タプルと分解」です。

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

C# — ブラウザ内で実行

ブラウザ内でC#を動かす環境を読み込みます(初回のみ数秒)。
スクロールして表示された時点でも自動で読み込まれます。