enum
を ビットフラグ として利用することはよくあると思いますが、
フラグとして利用する際、よく直面する フラグ操作(フラグ演算、判定) をまとめてみました。
目次
フラグ利用する enum の作成
ビット演算できるよう、数値は被らないように値を設定する必要があります。
おおよそ 2進数 における 各桁 が 1 となるような設定になります。
具体的には 1 (=2^0), 2 (=2^1), 4 (=2^2), 8 (=2^3), 16 (=2^4) … といった感じです。
フラグ利用する enum の場合、 Flags
属性 をつけるのもポイントです。
1 2 3 4 5 6 7 8 9 10 11 | [Flags] public enum Week { Sunday = 0x001, Monday = 0x002, Tuesday = 0x004, Wednesday = 0x008, Thursday = 0x010, Friday = 0x020, Saturday = 0x040 } |
上述の enum を 2進数、10進数で表に表わすと以下のようになります。
フラグ | 2進数 | 10進数 | 16進数 |
---|---|---|---|
Sunday | 0000001 (2) | 1 | 0x001 |
Monday | 0000010 (2) | 2 | 0x002 |
Tuesday | 0000100 (2) | 4 | 0x004 |
Wednesday | 0001000 (2) | 8 | 0x008 |
Thursday | 0010000 (2) | 16 | 0x010 |
Friday | 0100000 (2) | 32 | 0x020 |
Saturday | 1000000 (2) | 64 | 0x040 |
フラグ 演算
慣れないと難しいし、あまり使わないのでよく忘れがちですが… 基本はビット演算になります。 以下では基本となる追加と削除を例に記載します。
フラグを追加する
追加する場合、 |演算子(OR演算子) でつなげることで追加できます。
1 2 | var flag = Week.Monday; flag = flag | Week.Wednesday; |
フラグを削除する
削除する場合、 &演算子(AND演算子) と ~演算子(反転演算子) の組み合わせで削除できます。
1 2 | var flag = Week.Monday | Week.Wednesday; flag = flag & ~Week.Wednesday; |
フラグ 判定
どの フラグ が立っているかを判定する方法は 2通り あります。 1つは ビット演算、もう1つは HasFlags メソッド。 ビット演算 は昔からあるやり方で、ややクセがある が 速いフラグ判定方法だと思います。 新しく追加された HasFlags メソッド は簡単にフラグが立っているかどうかを判定でき、かつ、コードが読みやすい方法だと思います。
ビット演算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | var flag = Week.Monday | Week.Wednesday; // "flag" が "Monday" if ((flag & Week.Monday) == Week.Monday ) { // ... } // "flag" が "Monday かつ Wednesday" if ((flag & (Week.Monday | Week.Wednesday)) == (Week.Monday | Week.Wednesday)) { // ... } // "flag" が "Monday または Wednesday" if ((flag & (Week.Monday | Week.Wednesday)) != 0) { // ... } |
HasFlags メソッド
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | var flag = Week.Monday | Week.Wednesday; // "flag" が "Monday" if (flag.HasFlag(Week.Monday)) { // ... } // "flag" が "Monday かつ Wednesday" if (flag.HasFlag(Week.Monday) && flag.HasFlag(Week.Wednesday)) { // ... } // "flag" が "Monday または Wednesday" if (flag.HasFlag(Week.Monday) || flag.HasFlag(Week.Wednesday)) { // ... } |
最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!