150

In below lines:

//Folder.Attributes = FileAttributes.Directory | FileAttributes.Hidden | FileAttributes.System | FileAttributes.ReadOnly;
Folder.Attributes |= FileAttributes.Directory | FileAttributes.Hidden | FileAttributes.System | FileAttributes.ReadOnly;


Folder.Attributes |= ~FileAttributes.System;
Folder.Attributes &= ~FileAttributes.System;

What does |= (single pipe equal) and &= (single ampersand equal) mean in C#?

I want to remove system attribute with keeping the others...

Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
SilverLight
  • 19,668
  • 65
  • 192
  • 300

3 Answers3

207

They're compound assignment operators, translating (very loosely)

x |= y;

into

x = x | y;

and the same for &. There's a bit more detail in a few cases regarding an implicit cast, and the target variable is only evaluated once, but that's basically the gist of it.

In terms of the non-compound operators, & is a bitwise "AND" and | is a bitwise "OR".

EDIT: In this case you want Folder.Attributes &= ~FileAttributes.System. To understand why:

  • ~FileAttributes.System means "all attributes except System" (~ is a bitwise-NOT)
  • & means "the result is all the attributes which occur on both sides of the operand"

So it's basically acting as a mask - only retain those attributes which appear in ("everything except System"). In general:

  • |= will only ever add bits to the target
  • &= will only ever remove bits from the target
djeikyb
  • 4,470
  • 3
  • 35
  • 42
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
43

a |= b is equivalent to a = a | b except that a is evaluated only once
a &= b is equivalent to a = a & b except that a is evaluated only once

In order to remove the System bit without changing other bits, use

Folder.Attributes &= ~FileAttributes.System;

~ is bitwise negation. You will thus set all bits to 1 except the System bit. and-ing it with the mask will set System to 0 and leave all other bits intact because 0 & x = 0 and 1 & x = x for any x

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • 2
    What does it mean that `a` is only evaluated once? Why would it be evaluated more times than that? – silkfire Oct 20 '18 at 21:43
  • @silkfire This is called short-circuit evaluation, see https://en.wikipedia.org/wiki/Short-circuit_evaluation – Polluks Jan 16 '19 at 13:25
  • 1
    @Polluks So basically `a |= b` actually means `a = a || b`? – silkfire Jan 16 '19 at 14:27
  • @silkfire Yep but don't interchange one pipe and two pipes. – Polluks Jan 16 '19 at 14:51
  • 2
    @Polluks: I fail to understand your comment about one and two pipes - I think using two pipes instead of one was silkfire's entire point in that [last comment](https://stackoverflow.com/questions/6942477#comment95263986_6942502). Also, I am not convinced the statement "except that `a` is evaluated only once` does indeed refer to short-circuit evaluation, as short-circuit evaluation does not change the evaluation of the *first* operand ( `a` ), but might skip the evaluation of the *second* operand ( `b` ). – O. R. Mapper Nov 30 '20 at 10:57
  • @silkfire it means a "not lazy" ||, i.e. both parts of the expression are always calculated, whereas 2nd part of a standard "lazy" || may not be calculated. – Evgeni Nabokov Mar 02 '21 at 18:48
3

I want to remove system attribute with keeping the others..

You can do this like so:

Folder.Attributes ^= FileAttributes.System;
Chris S
  • 64,770
  • 52
  • 221
  • 239