3

私のオブジェクトItemには、組み合わせることができるいくつかのバイナリ状態があります

bool CanBeSold;
bool CanBeBought;
bool CanBeExchanged;

現在の値の組み合わせを 1 つの変数に格納する必要があります。その理由は、この値を DB に格納する必要があるためです。C++ では、1 つの状態がビットを占有するビットマスクを作成します。それは .NET での良い習慣ですか?

4

4 に答える 4

13

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) { ... }
于 2009-12-06T12:10:57.143 に答える
7

値が整数のビットに対応する列挙型を作成します。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)) ...
于 2009-12-06T12:15:12.437 に答える
2

.NET でもビット マスクを使用してこれを行うことができます。

列挙型内で、状態を値として定義できます

public enum ItemState { CanBeSold = 1; CanBeBought = 2; CanBeExchanged = 4 }

次に、オブジェクト内で次のことができます

if (item.State ^ ItemState.CanBeSold) ....
于 2009-12-06T12:11:23.943 に答える
2

各ビットを指定して 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;
于 2009-12-06T12:14:12.970 に答える