A clear, layman's explanation of the difference between | and || in c#?

后端 未结 11 510
余生分开走
余生分开走 2020-12-02 12:51

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 |         


        
相关标签:
11条回答
  • 2020-12-02 13:31

    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

    0 讨论(0)
  • 2020-12-02 13:34

    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.

    0 讨论(0)
  • 2020-12-02 13:38

    || 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.

    0 讨论(0)
  • 2020-12-02 13:38

    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).

    0 讨论(0)
  • 2020-12-02 13:40

    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.


    Consider the following Code Snippet

    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#

    0 讨论(0)
  • 2020-12-02 13:41

    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.

    0 讨论(0)
提交回复
热议问题