Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why bitwise OR operator is used in flag enum with meaning AND

Tags:

c#

.net

c#-4.0

It might be an easy and simple question but I still have a little confusion the reason why bitwise OR is decided to use. Assume I have a class A with four fields:

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

And use Reflection to get fields:

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

If you are newbie with Reflection and don't know the way how to use BindingFlags, the initial logic thinking in your head would be:

This line will select all static OR public fields because bitwise OR is used. And the expected result you think:

Field2
Field3
Field4

But when hitting F5, the result will be totally different, bitwise OR works as AND:

Field4

Why not use bitwise AND operator which might follow with the logic thinking. like this:

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

I found words in MSDN:

the bitwise OR operation used to combine the flags might be considered an advanced concept in some circumstances that should not be required for simple tasks.

Please could anyone explain the advance concept in here in simple way for understanding?

like image 575
cuongle Avatar asked Sep 19 '12 08:09

cuongle


People also ask

Why do we use Bitwise?

Because they allow greater precision and require fewer resources, bitwise operators can make some code faster and more efficient. Examples of uses of bitwise operations include encryption, compression, graphics, communications over ports/sockets, embedded systems programming and finite state machines.

What is a Bitwise flag?

Bit flags are one or more (up to 32) Boolean values stored in a single number variable. Each bit flag typically has a corresponding predefined constant associated with it; this constant has the bit for this flag set to 1 and all other bits set to 0.

What is the role of flag attribute in enum?

The [Flag] attribute is used when Enum represents a collection of multiple possible values rather than a single value. All the possible combination of values will come. The [Flags] attribute should be used whenever the enumerable represents a collection of possible values, rather than a single value.

What does Bitwise and represent?

A bitwise AND is a binary operation that takes two equal-length binary representations and performs the logical AND operation on each pair of the corresponding bits.


2 Answers

See the end for a short summary.

Long answer:

Bitwise OR is combining the bits of the enum flags.

Example:

  • BindingFlags.Public has the value of 16 or 10000 (binary)
  • BindingFlags.Static has the Value of 8 or 1000 (binary)

bitwise OR combines these like the following:

10000
01000
--
11000  --> 24

bitwise AND would combine them like this:

10000
01000
--
00000   --> 0

That's a very basic concept of Flags:
Each value is a power of two, e.g.:

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

Their bit representation is always a 1 and the rest zeros:

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

Combining any of them using bitwise AND would always lead to 0 as there are no 1 at the same position. Bitwise AND would lead to a complete information loss.

Bitwise OR on the other hand will always result in an unambiguous result. For example, when you have (binary) 1010 (decimal 10) you know it originally has been 8 and 2. There is no other possibility 10 could have been created.
As Default said, the method you called can later extract this information using the bitwise AND operator:

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

The bitwise OR in this case is basically a vehicle to transport the values to the method you are calling.
What this method does with these values has nothing to do with the usage of bitwise OR.
It can internaly require ALL passed flags to match as is the case for GetFields. But it also could require only one of the passed flags to match.

For you as a caller, the following would be equivalent:

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

Now that doesn't compile as GetFields doesn't provide such an overload, but the meaning would be the same as that of your code.

To sum things up (TL;DR):

Bitwise AND has nothing to do with Boolean AND
Bitwise OR has nothing to do with Boolean OR

like image 161
Daniel Hilgarth Avatar answered Oct 16 '22 02:10

Daniel Hilgarth


The flag enum is being used to represent a set of boolean conditions.

In your example, each boolean condition must be fulfilled for the corresponding field to be returned.

Flag enums are simply integral values that obey the usual binary rules for anding and oring, so to set several bits you must OR together the values representing those bits.

Once you have done so, you have a flag enum with the appropriate bits set.

The problem you are having is because you are conflating two different concepts: The way that you construct the set of boolean conditions for a flag enum is one concept. The way that the flag enum is used (or what it represents) is a different concept.

The former uses OR to construct the set of boolean conditions. The latter says that each bit represents a boolean condition that must be fulfilled.

like image 26
Matthew Watson Avatar answered Oct 16 '22 03:10

Matthew Watson