30

私は4つの旗を持っています

Current = 0x1  
Past = 0x2  
Future = 0x4  
All = 0x7

過去と未来の2つのフラグを受け取ったとします(setFlags(PAST | FUTURE))。中にあるかどうかはどうすればわかりPastますか?同様に、それが含まれていないことをどのように知ることCurrentができますか?そうすれば、考えられるすべての組み合わせをテストする必要はありません。

4

8 に答える 8

47

テストマスクのすべてのビットを一致させる場合:

if((value & mask) == mask) {...}

テストマスクの任意の1ビットを一致させる場合:

if((value & mask) != 0) {...}

違いは、複数のものの値をテストするときに最も明白になります。

除外をテストするには:

if ((value & mask) == 0) { }
于 2009-02-09T21:40:07.017 に答える
32

まず第一に-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;
于 2009-02-09T21:38:25.460 に答える
12

このような拡張メソッドを追加することもできます

  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
 }
于 2009-02-09T21:45:22.650 に答える
6

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
}
于 2014-09-22T19:15:12.640 に答える
4
if ((flags & PAST) == PAST)
{
  // PAST is there
}

if ((flags & CURRENT) != CURRENT)
{
  // CURRENT is not there
}
于 2009-02-09T21:37:30.220 に答える
0
(value & Current) == Current
于 2009-02-09T21:37:50.143 に答える