1

I've seen some explanations of & (and plenty of explanations of |) around SO (here etc), but none which clarify the use of the & in the following scenario:

else if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)  {...}

Taken from MSDN

Can anyone explain this, specific to this usage?

Thanks.

Community
  • 1
  • 1
cdsln
  • 830
  • 1
  • 11
  • 33
  • 2
    It checks if `DragDropEffects.Move` is one of the set flags in the `AllowedEffect` enum value. [This should be useful reading](http://stackoverflow.com/questions/8447/what-does-the-flags-enum-attribute-mean-in-c) – musefan Jun 03 '15 at 09:46
  • 2
    Note that the example is a little old. There is `e.AllowedEffect.HasFlag(DragDropEffects.Move)` from .NET 4. You may find that easier to understand. – Jesse Good Jun 03 '15 at 09:50
  • 1
    @JesseGood A better choice is most circumstances. But it has downsides: 1) It's slower 2) It's not obvious what will happen if you specify multiple flags. (It checks if all flags are set) – CodesInChaos Jun 03 '15 at 10:03

5 Answers5

1

Suppose :

DragDropEffects.Move has 1 value. e.AllowedEffect has 0 value.

It will do bitwise AND (1 & 0 = 0) of the 2 hence the result will be 0 currently:

DragDropEffects.Move & e.AllowedEffect will be 0 in this case.

Consider this now :

DragDropEffects.Move has 1 value. e.AllowedEffect has 1 value.

in that case bitwise AND will return 1 (as 1 & 1 = 1 in bitwise AND) so now the result will be 1.

Bitwise AND will return 0 if one of the bit is 0 which we are doing AND and will return 1 if all are set to 1.

The second answer in this post which you linked in your question explains it well.

Community
  • 1
  • 1
Ehsan Sajjad
  • 61,834
  • 16
  • 105
  • 160
1

e.AllowedEffect is possibly a combination of bitwise flags. The & operator performs a bit a bit "and" logical operation with each bit. As a result if the bit under test is one, the result is that single flag. The test could be writter in this way with exactly the same result:

else if ((e.AllowedEffect & DragDropEffects.Move) != 0 )  {...}

Lets explain better with an example, the flag value are these:

None = 0,

    Copy = 1,

    Move = 2,

    Link = 4,

So in binary:

None = 00000000,

Copy = 00000001,

Move = 00000010,

Link = 00000100,

So we consider the case in which under test we have the combination of Copy and Move, ie the value will be:

00000011

by bitwise and with move we have:

00000011  -->Copy | Move
00000010  -->Move
======== &
00000010 === Move
Felice Pollano
  • 32,832
  • 9
  • 75
  • 115
1

DragDropEffects.Move has one bit set, the second least significant making it the same as the number 2.

If you & something with 2 then if that bit is set you will get 2 and if that bit is not set, you will get 0.

So (x & DragDropEffects.Move) == DragDropEffects.Move will be true if the flag for DragDropEffects.Move is set in x and false otherwise.

In languages which allow automatic conversion to boolean it's common to use the more concise x & DragDropEffects.Move. The lack of concision is a disadvantage with C# not allowing such automatic conversion, but it does make a lot of mistakes just not happen.

Some people prefer the alternative (x & DragDropEffects.Move) != 0 (and conversely (x & DragDropEffects.Move) == 0 to test for a flag not being set) which has the advantage of 0 working here no matter what the enum type or what flag is tested. (And potentially a minor advantage in resulting in very slightly smaller CIL if it is turned straight into a brzero instruction, but I think it generally doesn't anyway).

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
0

DragDropEffects is not just enum, this is a set of flags, so in your example we check whether e.AllowedEffect has set bits for DragDropEffects.Move or not.

olegk
  • 765
  • 4
  • 13
0

hope you understand how bitwise operators work.

if e.AllowedEffect is set to DragDropEffects.Move then their & will result in either e.AllowedEffector DragDropEffects.Move i.e.

e.AllowedEffect = 1
DragDropEffects.Move = 1
e.AllowedEffect & DragDropEffects.Move = 1

from the MSDN example, it rouhhly means:

'if ActiveEffect is set/equal to DragDropEffects.Move then do this...'

h.i
  • 515
  • 1
  • 5
  • 16