14

OR簡単で単純な質問かもしれませんが、ビット単位の使用が決定された理由について、まだ少し混乱しています。A4 つのフィールドを持つクラスがあるとします。

class A
{
    private int Field1;
    private static int Field2;
    public int Field3;
    public static int Field4;
}

Reflectionフィールドを取得するために使用します。

var fields = typeof (A).GetFields(BindingFlags.Public | BindingFlags.Static);

あなたが の初心者でReflectionの使い方がわからない場合BindingFlags、頭の中で考える最初のロジックは次のようになります。

ビットごとの OR が使用されるため、この行はすべての静的 OR パブリック フィールドを選択します。そして、あなたが考える期待される結果:

Field2
Field3
Field4

しかし、F5 を押すと、結果はまったく異なります。ビットごとORの動作は次のようになりANDます。

Field4

論理的思考に従う可能性のあるビットごとの AND 演算子を使用してみませんか。このような:

var fields = typeof (A).GetFields(BindingFlags.Public & BindingFlags.Static);

MSDNで単語を見つけました:

フラグを結合するために使用されるビットごとの OR 演算は、状況によっては、単純なタスクには必要ない高度な概念と見なされる場合があります。

理解できるように、ここでの事前の概念を簡単に説明してもらえますか?

4

3 に答える 3

26

短い要約については、最後を参照してください。

長い答え:

ビットごとの OR は、列挙型フラグのビットを組み合わせています。

例:

  • BindingFlags.Public値は 16 または 10000 (バイナリ)
  • BindingFlags.Static値は 8 または 1000 (バイナリ)

ビットごとの OR は、これらを次のように結合します。

10000
01000
--
11000  --> 24

ビットごとの AND は、次のように結合します。

10000
01000
--
00000   --> 0

これはフラグの非常に基本的な概念です。
各値は 2 のべき乗です。たとえば、次のようになります。

  • 1 =2^0
  • 2 =2^1
  • 4 =2^2
  • 8 =2^3

それらのビット表現は常に a1で、残りはゼロです。

decimal | binary
1       | 0001
2       | 0010
4       | 0100
8       | 1000

1ビットごとの AND を使用してそれらのいずれかを組み合わせると、同じ位置にはないため、常に 0 になります。ビットごとの AND は、完全な情報損失につながります。

一方、ビットごとの OR は、常に明確な結果になります。たとえば、(バイナリ) 1010 (10 進数の 10) がある場合、元は 8 と 2 だったことがわかります。10 が作成された可能性は他にありません。
Default が言ったように、呼び出したメソッドは、後でビットごとの AND 演算子を使用してこの情報を抽出できます。

if(10 & 8 == 8) // value 8 was set

この場合のビットごとの OR は、基本的に、呼び出しているメソッドに値を転送する手段です。
このメソッドがこれらの値に対して行うことは、ビットごとの OR の使用とは関係ありません。
の場合と同様に、渡されたすべてのフラグが一致することを内部的に要求できますGetFields。しかし、渡されたフラグの 1 つだけが一致する必要がある場合もあります。

発信者としてのあなたにとって、以下は同等です。

var requiredFlags = new List<BindingFlags>();
requiredFlags.Add(BindingFlags.Public);
requiredFlags.Add(BindingFlags.Static);
typeof (A).GetFields(requiredFlags);

そのようなオーバーロードを提供しないため、コンパイルされGetFieldsませんが、意味はコードの意味と同じになります。

要約すると (TL;DR):

ビット単位の AND は、ブール値の AND とは何の関係もありませ
ん。ビット単位の OR は、ブール値の OR とは何の関係もありません。

于 2012-09-19T08:27:32.170 に答える
2

フラグ列挙型は、一連のブール条件を表すために使用されています。

あなたの例では、対応するフィールドが返されるためには、各ブール条件が満たされている必要があります。

フラグ列挙型は、AND と OR の通常の 2 項規則に従う単純な整数値であるため、複数のビットを設定するには、それらのビットを表す値を OR で結合する必要があります。

これを行うと、適切なビットが設定されたフラグ列挙型が得られます。

あなたが抱えている問題は、2 つの異なる概念を混同しているためです。フラグ列挙型のブール条件のセットを構築する方法は 1 つの概念です。フラグ列挙型の使用方法 (またはそれが表すもの) は、別の概念です。

前者は、OR を使用して一連のブール条件を構築します。後者は、各ビットが満たさなければならないブール条件を表していると言います。

于 2012-09-19T08:29:35.327 に答える
1

GetFields()の実装者は、さまざまなORされたフラグの組み合わせを、選択された基準のANDの組み合わせを意味するものとして解釈することを選択しました。

追加のフィルターが必要ない場合は、いつでも基準を削除できるため、これは理にかなっています。

于 2012-09-19T08:45:15.990 に答える