私のオブジェクトItem
には、組み合わせることができるいくつかのバイナリ状態があります
bool CanBeSold;
bool CanBeBought;
bool CanBeExchanged;
現在の値の組み合わせを 1 つの変数に格納する必要があります。その理由は、この値を DB に格納する必要があるためです。C++ では、1 つの状態がビットを占有するビットマスクを作成します。それは .NET での良い習慣ですか?
私のオブジェクトItem
には、組み合わせることができるいくつかのバイナリ状態があります
bool CanBeSold;
bool CanBeBought;
bool CanBeExchanged;
現在の値の組み合わせを 1 つの変数に格納する必要があります。その理由は、この値を DB に格納する必要があるためです。C++ では、1 つの状態がビットを占有するビットマスクを作成します。それは .NET での良い習慣ですか?
Flags
次の属性で列挙を使用できます。
[Flags]
enum MyStates {
CanBeSold = 1,
CanBeBought = 2,
CanBeExchanged = 4
}
列挙はその下にある整数データ型であるため、通常の方法でそれらを組み合わせることができます。
state = MyStates.CanBeSold | MyStates.CanBeExchanged
これは、enum 値が 2 の累乗の場合にのみ機能することに注意してください ( Doug Fergusonがコメントで指摘したように)。これらは簡単に組み合わせることができ、複数の値が設定されている場合でも重複しません。
他の複数の値の組み合わせとして値を定義することもできます。
CanBeSoldOrBought = CanBeSold | CanBeBought
また
CanBeSoldOrBought = 3
これも期待どおりに機能します。これは、たとえば、ReadWrite が通常は読み取りビットと書き込みビットの組み合わせであるファイル アクセス許可の場合に見られます。
はい、それは非常に一般的な方法です。フレームワーク自体もいくつかの場所で使用しています。
特定のビットが設定されているかどうかを確認する通常の方法は、次のとおりです。
if ((state & MyStates.CanBeSold) != 0) { ... }
値が整数のビットに対応する列挙型を作成します。Flags 属性を追加すると、列挙値に対してさらにビット操作を実行できるようになりました。
[Flags]
public enum CanBe {
Sold = 1,
Bought = 2,
Exchanged = 4
}
これで、値の間に or 演算子を使用できます。
CanBe can = CabBe.Sold | CanBe.Exchanged.
|= 演算子を使用して状態を追加できます。
can |= CanBe.Sold;
またはいくつかの状態:
can |= CanBe.Sold | CanBe.Bought;
&= 演算子を使用して状態を保持できます。
can &= CanBe.Sold;
またはいくつかの状態:
can &= CanBe.Sold | CanBe.Bought;
~ 演算子を使用して値の補数を作成することで、状態を削除できます。
can &= ~CabBe.Bough;
または複数の状態:
can &= ~(CabBe.Bough | CanBe.Exchanged);
& 演算子を使用して状態を確認できます。
if ((can & CanBe.Sold) != 0) ...
または、一度に複数の状態:
if ((can & (CanBe.Sold | CanBe.Bought)) != 0) ...
または、いくつかの状態がすべて設定されていることを確認します。
if ((can & (CanBe.Sold | CanBe.Bought)) == (CanBe.Sold | CanBe.Bought)) ...
.NET でもビット マスクを使用してこれを行うことができます。
列挙型内で、状態を値として定義できます
public enum ItemState { CanBeSold = 1; CanBeBought = 2; CanBeExchanged = 4 }
次に、オブジェクト内で次のことができます
if (item.State ^ ItemState.CanBeSold) ....
各ビットを指定して Flags 列挙型を使用できます
[Flags]
enum MyStates {
CanBeSold = 0x1,
CanBeBought = 0x2,
CanBeExchanged = 0x4,
}
MyStates m_Flags;
// to set a flag:
m_Flags |= MyStates.CanBeSold;
// to unset a flag:
m_Flags &= ~MyStates.CanBeSold;