私は4つの旗を持っています
Current = 0x1
Past = 0x2
Future = 0x4
All = 0x7
過去と未来の2つのフラグを受け取ったとします(setFlags(PAST | FUTURE)
)。中にあるかどうかはどうすればわかりPast
ますか?同様に、それが含まれていないことをどのように知ることCurrent
ができますか?そうすれば、考えられるすべての組み合わせをテストする必要はありません。
私は4つの旗を持っています
Current = 0x1
Past = 0x2
Future = 0x4
All = 0x7
過去と未来の2つのフラグを受け取ったとします(setFlags(PAST | FUTURE)
)。中にあるかどうかはどうすればわかりPast
ますか?同様に、それが含まれていないことをどのように知ることCurrent
ができますか?そうすれば、考えられるすべての組み合わせをテストする必要はありません。
テストマスクのすべてのビットを一致させる場合:
if((value & mask) == mask) {...}
テストマスクの任意の1ビットを一致させる場合:
if((value & mask) != 0) {...}
違いは、複数のものの値をテストするときに最も明白になります。
除外をテストするには:
if ((value & mask) == 0) { }
まず第一に-FlagAttributeで列挙型を使用します。それが目的です。
[Flags]
public enum Time
{
None = 0
Current = 1,
Past = 2,
Future = 4
All = 7
}
次に、テストは次のように行われます。
if ( (x & Time.Past) != 0 )
またはこれ:
if ( (x & Time.Past) == Time.Past )
「過去」がフラグの組み合わせであり、それらすべてをテストしたい場合は、後者の方がうまく機能します。
設定は次のようになります。
x |= Time.Past;
設定解除は次のようになります。
x &= ~Time.Past;
このような拡張メソッドを追加することもできます
enum states {
Current = 0x1,
Past = 0x2,
Future = 0x4,
All = 0x7
};
static bool Is(this states current, states value) {
return (current & value) == value;
}
次に、次のことができます。
if(state.Is(states.Past)) {
// Past
}
Marc Gravell と Vilx- の回答への補遺:
フラグ付きの列挙型では、「すべて」の金額を指定するべきではなく、既存の値のみを含める必要があります。これは、計算された値に当てはまります。
[Flags]
public enum Time
{
None = 0,
Current = 1,
Past = 2,
Future = 4,
All = Current | Past | Future
}
Vilx- が値の 16 進数の使用を削除したことに注意してください。0x8 を超えると、値は 16 進数に準拠する必要があるため、これは重要です。あなたはただ10進数のままであるべきです。
編集: 16進数/10進数ではなくビットシフトを使用できることも追加したいと思います。
これは次のようになります。
[Flags]
public enum Time
{
None = 0,
Current = 1,
Past = 1 << 1, // 2, 10 binary
Future = 1 << 2, // 4, 100 binary
// Example = 1 << 3, // 8, 1000 binary
// Example = 1 << 4, // 16, 10000 binary
All = Current | Past | Future
}
if ((flags & PAST) == PAST)
{
// PAST is there
}
if ((flags & CURRENT) != CURRENT)
{
// CURRENT is not there
}
(value & Current) == Current