私は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
}
if ((flags & PAST) == PAST)
{
// PAST is there
}
if ((flags & CURRENT) != CURRENT)
{
// CURRENT is not there
}
.NET 4以降を使用している場合は、これを実行することをお勧めします。よりクリーンなimao:
[Flags]
public enum Time
{
None = 0
Current = 1,
Past = 2,
Future = 4
}
myProp = Time.Past | Time.Future;
if (myProp.HasFlag(Time.Past))
{
// Past is set...
}
Marc GravellとVilx-の回答の補遺:
フラグが立てられた列挙型は、「すべて」の量を指定するのではなく、既存の値を含める必要があります。これは、計算された値に当てはまります。
[Flags]
public enum Time
{
None = 0,
Current = 1,
Past = 2,
Future = 4,
All = Current | Past | Future
}
Vilx-は値に16進数の使用を削除したことに注意してください。 0x8を超えると、値は16進数に準拠する必要があるため、これは重要です。 10進数のままにする必要があります。
EDIT: 1進数/ 10進数ではなくビットシフトを使用できることも追加したいと思います。
これは次のようになります。
[Flags]
public enum Time
{
None = 0,
Current = 1,
Past = 1 << 1, // 2, 10 binary
Future = 1 << 2, // 4, 100 binary
All = Current | Past | Future
}
(value & Current) == Current