2012-09-19 7 views
12

簡単で簡単な質問かもしれませんが、ビット単位でORが使用される理由は少し混乱しています。私は四つのフィールドを持つクラスAがあるとします。意味があるフラグ列挙型でビット単位のOR演算子が使用されています

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

とフィールドを取得するためにReflectionを使用:あなたはReflectionと初心者であり、BindingFlagsを使用するための仕方がわからない場合は

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

を、

この行は、ビット単位のORが使用されるため、すべてのスタティックORパブリックフィールドを選択します。そして、期待と思う結果:

Field2 
Field3 
Field4 

しかし、F5キーを押すとき、結果はビットごとANDとしてOR作品、全く異なるものになります:

Field4 

はなぜビット単位のAND演算子を使用しないで続くかもしれません論理思考。このように:

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

私はMSDNに言葉が見つかりました:

フラグを結合するために使用されるビット単位のOR演算を単純なタスクのために要求されるべきではない、いくつかの状況では、高度な概念と考えられるかもしれません。

ここではアドバンスコンセプトを簡単に説明することができますか?

+1

包括的排他的論理和の違いを考慮すると、ここでは「OR」が正しい概念であるようです。この場合、「OR」は包括的であり、「卵またはハムを含む店からいくつかのアイテムを拾う」と同じである。それは「卵とハムを含んでいる」と違う。 –

+0

[MSDN](http://msdn.microsoft.com/en-us/library/6ztex2dc.aspx)を参照してください。戻り値を取得するには、BindingFlags.Instance **または** BindingFlags.Staticのいずれかを指定する必要があります。だから、インスタンス**と**静的を同時に列挙できないかもしれません...? – tschmit007

+0

@ tschmit007:それは質問と何が関係していますか? –

答えて

25

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

長い答え:

ビット単位のOR列挙フラグのビットを組み合わせています。

例:

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

ビット単位の値を有するか、または以下のように、これらを組み合わせました:

10000 
01000 
-- 
11000 --> 24 

ビット単位でANDをとりますE本:
各値が2の累乗が、ある例えば:フラグの非常に基本的な考え方だ

10000 
01000 
-- 
00000 --> 0 

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

それらのビット表現が常に1、残りゼロ:

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

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

一方、ビット単位のORは、常に明確な結果になります。たとえば、(バイナリ)1010(10進数)の場合、元々8と2になっています。
デフォルトが言ったように、あなたが後でビット単位の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

+1

**後で**は '&'演算子と共に 'if(userArgument&BindingFlags.Public){/ *戻り値に* /}'として使用されます。 – Default

2

を持っていませんブール条件の集合を表す。

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

フラグenumは、andingとoringの通常のバイナリルールに従う単純な整数値です。したがって、いくつかのビットを設定するには、これらのビットを表す値をORで結合する必要があります。

これを実行すると、フラグenumに適切なビットが設定されます。

あなたが持っている問題は、2つの異なるコンセプトが融合しているためです。フラグ列挙型のブール条件セットを構成する方法は1つの概念です。フラグ列挙体の使用方法(またはその表現方法)は、別の概念です。

前者は、ブール条件のセットを構成するためにORを使用します。後者は、各ビットが満たされなければならないブール条件を表すと述べている。

1

GetFields()の実装者は、に、を選択し、さまざまなORedフラグの組み合わせを選択した条件のANDの組み合わせとして解釈しました。

フィルタを追加したくない場合は、いつでも基準を削除できるので意味があります。