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

后端 未结 11 511
余生分开走
余生分开走 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:45

    The first, bitwise operator works on two numerical values and results in a third one.

    If you have binary variables

    a = 0001001b;
    b = 1000010b;
    

    then

    a | b == 1001011b;
    

    That is, a bit in the result is 1 if it is also 1 in either of the operands. (My example uses 8-bit numbers for clarity's sake)

    The "double pipe" ||, is a logical OR operator that takes two boolean values and results in a third.

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

    When used with boolean operands the | operator is a logical operator just as ||, but the difference is that the || operator does short circuit evaluation and the | operator does not.

    This means that the second operand is always evaluated using the | operator, but using the || operator the second operand is only evaluated if the first operand evaluates to false.

    The result of the expression is always the same for both operatrors, but if the evaluation of the second operand causes something else to change, that is only guaranteed to happen if you use the | operator.

    Example:

    int a = 0;
    int b = 0;
    
    bool x = (a == 0 || ++b != 0);
    
    // here b is still 0, as the "++b != 0" operand was not evaluated
    
    bool y = (a == 0 | ++b != 0);
    
    // here b is 1, as the "++b != 0" operand was evaluated.
    

    The short-circuit evaluation of the || operator can be used to write shorter code, as the second operand only is evaluated if the first operand is true. Instead of writing like this:

    if (str == null) {
       Console.WriteLine("String has to be at least three characters.");
    } else {
       if (str.Length < 3) {
          Console.WriteLine("String has to be at least three characters.");
       } else{
          Console.WriteLine(str);
       }
    }
    

    You can write like this:

    if (str == null || str.Length < 3) {
       Console.WriteLine("String has to be at least three characters.");
    } else{
       Console.WriteLine(str);
    }
    

    The second operand is only evaluated if the first is false, so you know that you can safely use the string reference in the second operand as it can not be null if the second operand is evaluated.

    In most cases you would want to use the || operator rather than the | operator. If the first operand is false, there is no need to evaluate the second operand to get the result. Also, a lot of people (evidently) doesn't know that you can use the | operator with boolean operands, so they would get confused when seeing it used that way in the code.

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

    | is a bitwise OR operator (numeric, integer). it works by converting the numbers into binary and doing an OR for each of the corresponding digits. then again, numbers are already represented in binary in the computer, so no such conversion really takes place at runtime ;)

    || is a logical OR operator (boolean). it only works on true and false values.

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

    They are not the same. One is bitwise OR and one is logical OR.

    X || Y , is a logical or, means the same as "X or Y" and applies to bool values. It is used in conditionals or tests. X and Y in that case can be replaced with any expression that evaluates to a bool. Example:

    if (File.Exists("List.txt")  ||  x > y )  { ..}
    

    The clause evaluates to true if either of the two conditions is true. If the first condition is true (if the file exists), then the second condition need not and will not be evaluated.

    The single pipe ( | ) is a bitwise OR. To know what this means you must be understand how numbers are stored in the computer. Suppose you have a 16-bit quantity (Int16) that holds the value 15. It is actually stored as 0x000F (in hex) which is the same as 0000 0000 0000 1111 in binary. The bitwise OR takes two quantities and OR's each pair of corresponding bits together, so that if the bit is 1 in either quantity, it is 1 in the result. Therefore, if a = 0101 0101 0101 0101 (which evaluates to 0x5555 in hex) and b = 1010 1010 1010 1010 (which is 0xAAAA), then a | b = 1111 1111 1111 1111 = 0xFFFF.

    You can use bitwise OR's (single pipe) in C# to test if one or more of a particular set of bits is turned on. You might do this if you have, let's say, 12 booleans or binary values to test for, and they are all independent. Suppose you have a student database. A set of independent booleans might be things like, male/female, home/on-campus, current/not-current, enrolled/not-enrolled, etc. Rather than store a boolean field for each one of those values, you could store just a single bit for each one. The male/female might be bit 1. enrolled/not might be bit 2.

    Then you can use

     if ((bitfield | 0x0001) == 0x0001) { ... }
    

    as a test to see if no bits are turned on, except the "student is male" bit, which is ignored. Huh? Well, the bitwise OR returns a 1 for each bit that is on in either number. If the result of the bitwise OR above = 0x0001, that means there are no bits turned on in the bitfield, except maybe the first bit (0x0001), but you can't tell for sure whether the first bit is on, because it it is masked.

    There is a corresponding && and &, which is logical AND and bitwise AND. They have the analogous behavior.

    You can use

     if ((bitfield &  0x0001) == 0x0001) { ... }
    

    to see if the first bit is turned on in a bitfield.

    EDIT: I can't believe I got voted down for this!

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

    Unlike what most of the answers so far say, the meaning is not exactly the same as in C++.

    For any two expressions A and B evaluating to booleans, A || B and A | B do almost the same thing.

    A | B evaluates both A and B, and if one of them evaluates to true, the result is true.

    A || B does almost the same thing, except it evaluates A first, and then only evaluates B if it is necessary. Since the entire expression is true if either A or B is true, B doesn't need to be tested at all if A is true. So || short-circuits, and skips evaluating the second operand when possible, where the | operator will always evaluate both.

    The | operator isn't often used, and often it won't make a difference. The only common case I can think of where it'd make a difference is this:

    if ( foo != null || foo.DoStuff()){ // assuming DoStuff() returns a bool
    
    }
    

    This works because the DoStuff() member function is never called if the left test fails. That is, if foo is null, we don't call DoStuff on it. (which would give us a NullReferenceException).

    If we'd used the | operator, DoStuff() would be called regardless of whether foo was null or not.

    On integers, only the | operator is defined, and is a bitwise OR, as the other answers describe. The || operator isn't defined for integer types though, so it's hard to get them mixed up in C#.

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