Ok, so I\'ve read about this a number of times, but I\'m yet to hear a clear, easy to understand (and memorable) way to learn the difference between:
if (x |
Although it's already been said and answered correctly I thought I'd add a real layman's answer since alot of the time that's what I feel like on this site :). Plus I'll add the example of & vs. && since it's the same concept
| vs ||
Basically you tend to use the || when you only wnat to evaluate the second part IF the first part it FALSE. So this:
if (func1() || func2()) {func3();}
is the same as
if (func1())
{
func3();
}
else
{
if (func2()) {func3();}
}
This may be a way to save processing time. If func2() took a long time to process, you wouldn't want to do it if func1() was already true.
& vs &&
In the case of & vs. && it's a similar situation where you only evaluate the second part IF the first part is TRUE. For example this:
if (func1() && func2()) {func3();}
is the same as
if (func1())
{
if (func2()) {func3();}}
}
This can be necessary since func2() may depend on func1() first being true. If you used & and func1() evaluated to false, & would run func2() anyways, which could cause a runtime error.
Jeff the Layman
Without delving into the details in any way, shape, or form, here's a real layman's version.
Think of "|" as a straight "or" in english; think of "||" as "or else" in english.
Similarly think of "&" as "and" in english; think of "&&" as "and also" in english.
If you read an expression to yourself using these terms, they often make a lot more sense.
||
is the logical-or operator. See here. It evaluates to true
if at least one of the operands is true. You can only use it with boolean operands; it is an error to use it with integer operands.
// Example
var one = true || bar(); // result is true; bar() is never called
var two = true | bar(); // result is true; bar() is always called
|
is the or operator. See here. If applied to boolean types, it evaluates to true
if at least one of the operands is true. If applied to integer types, it evaluates to another number. This number has each of its bits set to 1 if at least one of the operands has a corresponding bit set.
// Example
var a = 0x10;
var b = 0x01;
var c = a | b; // 0x11 == 17
var d = a || b; // Compile error; can't apply || to integers
var e = 0x11 == c; // True
For boolean operands, a || b
is identical to a | b
, with the single exception that b
is not evaluated if a
is true. For this reason, ||
is said to be "short-circuiting".
If the difference a given piece of code has between them is irrelevant, which should I default to as a best-practise?
As noted, the difference isn't irrelevant, so this question is partially moot. As for a "best practice", there isn't one: you simply use whichever operator is the correct one to use. In general, people favor ||
over |
for boolean operands since you can be sure it won't produce unnecessary side effects.
Good answers, but let me add that the right-side expressions for ||
is not evaluated if the left-side expression is true
. Keep this in mind for cases where the evaluation terms are a) performance-intensive or b) produce side effects (rare).
Strongly recommend to read this article from Dotnet Mob
For OR logical operation if any of it's operand is evaluated to true then whole expression is evaluated to true
this is what || Operator does - it skips the remaining evaluation when it found a true. While | Operator evaluate it's complete operands to asses the value of whole expression.
if(true||Condition1())//it skip Condition1()'s evaluation
{
//code inside will be executed
}
if(true|Condition1())//evaluates Condition1(), but actually no need for that
{
//code inside will be executed
}
It is better to use Short Circuited version of Logical Operator Whether it is OR(||) or AND(&&) Operator.
int i=0;
if(false||(++i<10))//Now i=1
{
//Some Operations
}
if(true||(++i<10))//i remains same, ie 1
{}
This effect is called side effect, actually seen in right side of expression in short circuited logical operators
Reference : Short-circuit Evaluation in C#
The following would work in C/C++ because it has no first class support for booleans, it treats every expression with "on" bit on them as true otherwise false. In fact, the following code would not work in C# or Java if x and y are of numeric types.
if (x | y)
So the explicit version of above code is:
if ( (x | y) != 0)
In C, any expression which would have an "On" bit on them, results to true
int i = 8;
if (i) // valid in C, results to true
int joy = -10;
if (joy) // vaild in C, results to true
Now, back to C#
If x and y are of numeric type, your code: if (x | y) will not work. Have you tried compiling it? It will not work
But for your code, which I could assume x and y are of boolean types, so it will work, so the difference between | and || for boolean types, the || is short-circuited, the | is not. The output of the following:
static void Main()
{
if (x | y)
Console.WriteLine("Get");
Console.WriteLine("Yes");
if (x || y)
Console.WriteLine("Back");
Console.ReadLine();
}
static bool x
{
get { Console.Write("Hey"); return true; }
}
static bool y
{
get { Console.Write("Jude"); return false; }
}
is:
HeyJudeGet
Yes
HeyBack
Jude won't be printed twice, the || is a boolean operator, many C-derived languages boolean operators are short-circuited, boolean expressions are more performant if they are short-circuited.
As for layman terms, when you say short-circuited, for example in || (or operator), if the first expression is already true, no need to evaluate the second expression. Example: if (answer == 'y' || answer == 'Y'), if the user press small y, the program don't need to evaluate the second expression(answer == 'Y'). That's short-circuit.
On my sample code above, X is true, so the Y on || operator won't be evaluated further, hence no second "Jude" output.
Don't use this kind of code in C# even if X and Y are of boolean types: if (x | y). Not performant.