導入
権限(読み取り・書き込み・実行)のように、複数の選択肢を同時に持たせたいことがあります。[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/&で含有判定- 土台のビット演算
<< & | ^も覚えておく
次回: 複数の値を軽くまとめる「タプルと分解」です。