私は次のような列挙型を持っています:
public enum Blah
{
RED = 2,
BLUE = 4,
GREEN = 8,
YELLOW = 16
}
Blah colors = Blah.RED | Blah.BLUE | Blah.YELLOW;
可変色から青を削除するにはどうすればよいですか?
.ToString()
値を提供します。例えば、とRED, BLUE, YELLOW
いうより22
。
私は次のような列挙型を持っています:
public enum Blah
{
RED = 2,
BLUE = 4,
GREEN = 8,
YELLOW = 16
}
Blah colors = Blah.RED | Blah.BLUE | Blah.YELLOW;
可変色から青を削除するにはどうすればよいですか?
.ToString()
値を提供します。例えば、とRED, BLUE, YELLOW
いうより22
。
回答:
「BLUE」の(補数)で&
それをする必要があり~
ます。
補数演算子は基本的に、指定されたデータ型のすべてのビットを反転または「反転」します。そのため、ある値(その値を 'X'と呼びましょう)および1つ以上のセットビットの補数(これらのビットとその補数を呼びましょう)でAND
演算子(&
)を使用すると、ステートメントは、from と結果を返します。Q
~Q
X & ~Q
Q
X
したがって、BLUE
ビットを削除またはクリアするには、次のステートメントを使用します。
colorsWithoutBlue = colors & ~Blah.BLUE
colors &= ~Blah.BLUE // This one removes the bit from 'colors' itself
次のように、クリアする複数のビットを指定することもできます。
colorsWithoutBlueOrRed = colors & ~(Blah.BLUE | Blah.RED)
colors &= ~(Blah.BLUE | Blah.RED) // This one removes both bits from 'colors' itself
または代わりに...
colorsWithoutBlueOrRed = colors & ~Blah.BLUE & ~Blah.RED
colors &= ~Blah.BLUE & ~Blah.RED // This one removes both bits from 'colors' itself
要約すると:
X | Q
ビットを設定します Q
X & ~Q
ビットをクリアします Q
~X
すべてのビットを反転/反転します X
colors &= ~( Blah.BLUE | Blah.GREEN );
And not
それ...............................
Blah.RED | Blah.YELLOW ==
(Blah.RED | Blah.BLUE | Blah.YELLOW) & ~Blah.BLUE;
これは、私のようにここでつまずいた他の人々にとって役立つかもしれないと思いました。
値が== 0になるように設定した列挙値の処理方法に注意してください(列挙型の状態が不明またはアイドルになると役立つ場合があります)。これらのビット操作操作に依存すると問題が発生します。
また、他の2の累乗値の組み合わせである列挙値がある場合、たとえば
public enum Colour
{
None = 0, // default value
RED = 2,
BLUE = 4,
GREEN = 8,
YELLOW = 16,
Orange = 18 // Combined value of RED and YELLOW
}
このような場合、次のような拡張メソッドが役立ちます。
public static Colour UnSet(this Colour states, Colour state)
{
if ((int)states == 0)
return states;
if (states == state)
return Colour.None;
return states & ~state;
}
また、結合された値を処理する同等のIsSetメソッド(少しハッキーな方法ですが)
public static bool IsSet(this Colour states, Colour state)
{
// By default if not OR'd
if (states == state)
return true;
// Combined: One or more bits need to be set
if( state == Colour.Orange )
return 0 != (int)(states & state);
// Non-combined: all bits need to be set
return (states & state) == state;
}
none
かunknown
、またはunset
あなたが唯一の赤、青、緑のは、あなたがレッドなどを持ってしようとしているがあれば、いつでも例えば、特定の値がデフォルト設定されていると想定することはできませんとしての値== 0のエントリは、多くの場合、良いことですデフォルト値(たとえば、列挙が作成されたとき、またはユーザーが変更していないときの列挙)
1, 2, 4, 8
て、値として使用できませんか?デフォルト値が必要な場合、それがデフォルトコンストラクターの目的です。読みやすさを考慮して、できる限り明示的に説明したいと思います。値が指定されていない場合、列挙型をデフォルトのdefault(int)
(0
)に依存することは、おそらく開発者に知られている情報であるにもかかわらず、とにかく卑劣すぎるためです。編集:まあ、Unset = 0にすると何かができなくなりUnset | Blue
ますか?
Red & ~Red
最終的にゼロになる場合は、このケースをチェックしてUnset
値を明示的に割り当てるコードが必要になります)
xor(^)はどうですか?
削除しようとしているFLAGがそこにある場合、それは機能します。そうでない場合は、&を使用する必要があります。
public enum Colour
{
None = 0, // default value
RED = 2,
BLUE = 4,
GREEN = 8,
YELLOW = 16,
Orange = 18 // Combined value of RED and YELLOW
}
colors = (colors ^ Colour.RED) & colors;
フラグの列挙型を単純化し、倍数を避けて読む方がよい場合は、ビットシフトを使用できます。(列挙型フラグに関する大論争を終わらせる良い記事から)
[FLAG]
Enum Blah
{
RED = 1,
BLUE = 1 << 1,
GREEN = 1 << 2,
YELLOW = 1 << 3
}
また、すべてのビットをクリアする
private static void ClearAllBits()
{
colors = colors & ~colors;
}