0

I was looking up some beginner lessons on "csharp-station.com" to review my knowledge on C#. For AND and OR operators, I've always used "&&" and "||" like everybody else. I didn't even know there is a single version of those.

It's stated as follows:

About OR: "The primary difference between the two OR forms are that the regular OR operator will evaluate both sub-expressions every time. However, the conditional OR will evaluate the second sub-expression only if the first sub-expression evaluates to false."

About AND: "The difference between the two is that the regular AND operator will evaluate both expressions every time. However, the conditional AND operator will evaluate the second sub-expression only when the first sub-expression evaluates to true."

And it concludes as: "The conditional operators (&& and ||) are commonly called short-circuit operators because they do not always evaluate the entire expression. Thus, they are also used to produce more efficient code by ignoring unnecessary logic."

So is that all? Is there even a single code sample where using the regular operators are more plausible? I know the question is trivial, but I'm just curious. Thanks in advance.

Emre Can Serteli
  • 389
  • 1
  • 7
  • 17
  • Are you asking why you would want to use `&`/`|` in a *logical*, non-short-circuited conext? If so see http://stackoverflow.com/questions/9264897/reason-for-the-exsistance-of-non-short-circuit-logical-operators (its Java but applies here) – Alex K. Feb 13 '15 at 12:10
  • They're pretty useful on integers where they act as bitwise operators. I use them all the time in cryptographic code. – CodesInChaos Feb 13 '15 at 12:33

4 Answers4

2

As you say, these operators don't short-circuit. But that's not all: they're used for bit manipulation. Some examples:

Set the 4th bit:

// 00000010 | 00001000 == 00001010
value = value | (1 << 3);

Clear the 4th bit:

// ~00001000 == 11110111
// 00001010 & 11110111 == 00000010
value = value & ~(1 << 3);

Check if the 4th bit is set:

// 00001010 & 00001000 == 00001000
if ((value & (1 << 3)) != 0)
   ...

In C#, this is commonly used with flag enums (enum types with the [Flags] attribute applied).

Here's an example from the framework:

[Flags]
public enum FileAttributes
{
    ReadOnly = 0x1,
    Hidden = 0x2,
    System = 0x4,
    Directory = 0x10,
    Archive = 0x20,
    Device = 0x40,
    Normal = 0x80,

    // and so on...
}

So for instance you could test if a file is hidden using code like:

if ((attributes & FileAttributes.Hidden) != 0)
    ...
Lucas Trzesniewski
  • 50,214
  • 11
  • 107
  • 158
2

The main difference is if the expressions have side effects and if you want those side effects to always occur

public bool A()
{
    Console.WriteLine("A");
    return true;
}

public bool B()
{
    Console.WriteLine("B");
    return false;
}

With the above methods the following

if(A() || B())
    Console.WriteLine("A or B");

and this

if(A() | B())
    Console.WriteLine("A or B");

Will print out different results.

With that said depending on these side effects is a bad idea. So, in general the use of non-short-curcuited logical operators is only useful for cases that would be considered poor design. So, any time you find that you need to use them it most likely means there is a flaw in the design of the code.

But as others have mentioned the & and | operators are also used for bitwise "AND" and "OR", which is different from using them with bool expressions.

juharr
  • 31,741
  • 4
  • 58
  • 93
  • But if you execute `A` and `B` for their side-effects, you should put them in their own statements. – CodesInChaos Feb 13 '15 at 12:13
  • @CodesInChaos I'm not saying this is best practice, just that this is where the difference lies. – juharr Feb 13 '15 at 12:15
  • The OP knows the difference, but wonders why you'd want to use the non short circuiting variant. – CodesInChaos Feb 13 '15 at 12:16
  • @CodesInChaos The OP is quoting description from a website. It's not 100% clear if the OP understands that expressions can have side effects. And that's really the only time it makes a different regardless of whether that is bad design or not. But I have added a disclaimer to that effect. – juharr Feb 13 '15 at 12:24
1

They perform binary (base 2) calculations. See bitwise operations.

|  OR   
&  AND
^  XOR
~  NOT

These are the basic machine operations, used by all computers.
Computers love them, but most programmers prefer decimal arithmetic and enums.

0

There's hypothetical scenarios for these operators. As already written, all of them involve side-effects.

Imagine, you have a web-registration form with username, password, confirmation fields.

You should validate user's input after POST. You're planning to use simple validation methods that returns bool, f.e. IsUsernameAvailable, IsUsernameValid, IsPasswordComplexEnough, and ArePasswordAndConfirmationEquals. All of these methods has a single input/output parameter IList<string> containing error messages.

Then your entire validation method may look like this:

private bool ValidateAll(IList<string> errorMessages)
{
    return IsUsernameAvailable(errorMessages)
         | IsUsernameValid(errorMessages)
         | IsPasswordComplexEnough(errorMessages)
         | ArePasswordAndConfirmationEquals(errorMessages);
}
Mark Shevchenko
  • 7,937
  • 1
  • 25
  • 29