#1,201 – Writing Conditional Logical Operators as Conditionals

The conditional logical operators (&&, ||) can short-circuit evaluation, based on the value of the left side of the expression.

• For &&, evaluation short-circuits if left-side is false (result is false)
• For ||, evaluation short-circuits if left-side is true (result is true)

You can also think of the conditional logical operators as being equivalent to the ternary conditional operator.

```            bool leftSide = true;
bool rightSide = false;

// Short-circuits (right side not evaluated)
bool bResult = leftSide || rightSide;

// || Equivalent to
bResult = leftSide ? true : rightSide;

// Short-circuits if left side is false
bResult = leftSide && rightSide;

// && Equivalent to
bResult = leftSide ? rightSide : false;
```

#1,200 – Logical Operators vs. Conditional Logical Operators

You can use either the logical operators (|, &) or the conditional logical operators (||, &&) when comparing two boolean values (or expressions).

```            bool isFromMN = true;
bool likesConfrontation = false;

bool bResult = likesConfrontation & isFromMN;  // false
bResult = likesConfrontation && isFromMN;      // false
bResult = likesConfrontation | isFromMN;       // true
bResult = likesConfrontation || isFromMN;       // true
```

The difference between these operators, when used with boolean values, is that the conditional logical operators can short-circuit evaluation, avoiding evaluation of the right side of the expression if possible.

```            int val = 0;

// Short-circuits (right side not evaluated)
bResult = isFromMN || ((5 / val) == 1);     // true

// Throws exception (does not short-circuit)
bResult = isFromMN | ((5 / val) == 1);
```

#1,199 – Equality and Inequality with Nullable Types

The equality and inequality operators work with nullable types as follows:

• If both operands are non-null, the operators are applied to the values
• If one operand is null and the other has a value, == returns false, != returns true
• If both operands are null, == returns true and != returns false
```            int? val1 = 5;
int? val2 = 10;
int? val3 = null;
int? val4 = null;
int? val5 = 10;

bool b1 = val1 == val2;   // False
b1 = val2 == val5;        // True
b1 = val1 == val3;        // False
b1 = val1 != val3;        // True
b1 = val3 == val4;        // True
b1 = val3 != val4;        // False
```

#1,114 – Don’t Use Shift Operators to Do Multiplication

When you use the shift operators on integer-based values, you effectively multiply a number by two when you do a left shift by one bit and divide a number by two when you do a right shift by one bit.

In years past, you’d sometimes hear a recommendation that you should prefer using the shift operators over multiplicative operators because the shift operators were faster.

With modern optimizing compilers, you should no longer worry about this level of optimization and performance.  If you need to multiply a number by a power of two, you should express your intent by using the multiplicative operators.  (E.g. “* 2” or “* 4”).  The compiler will figure out that fastest way to accomplish this.

#1,110 – The Bitwise Exclusive OR Operator

You can use the ^ operator to do a bitwise exclusive OR (“XOR”) operation between two integer-based values.

An exclusive OR operation is applied to two different bits, returning true if exactly one of the input bits is true.  Here is a truth table showing the output value for all possible input combinations.

• 0 ^ 0 = 0
• 0 ^ 1 = 1
• 1 ^ 0 = 1
• 1 ^ 1 = 0

You can use the ^ operator on two arbitrary integer values as shown below.  The operation is applied to the two integer values, one bit at a time.

```            int n1 = 12;
int n2 = 10;
int result = n1 ^ n2;
Console.WriteLine("{0} ^ {1} = {2}", n1, n2, result);
```

It may help to use hex notation in order to better understand how the exclusive OR operation works on each bit.

```            int n1 = 0xC;  // 12 (dec) or 1100 (bin)
int n2 = 0xA;  // 10 (dec) or 1010 (bin)

// Result = 0110 bin (6 dec)
int result = n1 ^ n2;
```

#1,109 – The Bitwise NOT Operator

You can use the ~ operator to do a bitwise NOT operation on an integer-based value.

A NOT operation is applied to a single input bit, returning true if the input bit is false, or false if it is true.  The NOT operator “flips” or “negates” the input bit.  Here is a truth table showing the output value for the possible input values.

• ~0  = 1
• ~1 = 0

You can use the ~ operator on an arbitrary integer value as shown below.  The NOT operation will be applied to the integer value, one bit at a time.

```            int n = 5;
int result = ~n;
Console.WriteLine("~{0} = {1}", n, result);
```

It may help to use hex notation in order to better understand how the NOT operation works on each bit.

```            int n = 0x00000005;
int result = ~n;
Console.WriteLine(  "~{0:X8} = {1:X8}", n, result);
```

#1,108 – The Bitwise OR Operator

You can use the | operator to do a bitwise OR operation between two integer-based values.

An OR operation is applied to two different bits, returning true if either one or both input bits are true.  Here is a truth table showing the output value for all possible input combinations.

• 0 | 0 = 0
• 0 | 1 = 1
• 1 | 0 = 1
• 1 | 1 = 1

You can use the | operator on two arbitrary integer values as shown below.  The OR operation will be applied to the two integer values, one bit at a time.

```            int n1 = 12;
int n2 = 10;
int result = n1 | n2;
Console.WriteLine("{0} | {1} = {2}", n1, n2, result);
```

It may help to use hex notation in order to better understand how the OR operation works on each bit.

```            int n1 = 0xC;  // 12 (dec) or 1100 (bin)
int n2 = 0xA;  // 10 (dec) or 1010 (bin)

// result = 1110
int result = n1 | n2;
```

#1,107 – The Bitwise AND Operator

You can use the & operator to do a bitwise AND operation between two integer-based values.

An AND operation is applied to two different bits, returning true if both input bits are true.  Here is a truth table showing the output value for all possible input combinations.

• 0 & 0 = 0
• 0 & 1 = 0
• 1 & 0 = 0
• 1 & 1 = 1

You can use the & operator on two arbitrary integer values as shown below.  The AND operation will be applied to the two integer values, one bit at a time.

```            int n1 = 12;
int n2 = 10;
int result = n1 & n2;
Console.WriteLine("{0} & {1} = {2}", n1, n2, result);
```

It may help to use hex notation in order to better understand how the AND operation works on each bit.

```            int n1 = 0xC;  // 12 (dec) or 1100 (bin)
int n2 = 0xA;  // 10 (dec) or 1010 (bin)

// result = 1000
int result = n1 & n2;
```

#1,106 – Using the Logical Exclusive OR Operator

You can use the exclusive OR (^) operator to do a bitwise exclusive OR operation.  The operands in this case are integer-based types.

You can also use the exclusive OR operator on boolean operands.  The result of the operation is true if exactly one of the operands (but not both) is true.

• false ^ false => false
• false ^ true => true
• true ^ false => true
• true ^ true => false
```            bool itsThursday = DateTime.Now.DayOfWeek == DayOfWeek.Thursday;
bool itsMay = DateTime.Now.Month == 5;

// Wear red shirt in May, wear red shirt every Thursday,
// but don't wear red shirt on Thursdays in May
bool wearRedShirt = itsThursday ^ itsMay;

Console.WriteLine("Thursday:{0}, May:{1}, RedShirt:{2}", itsThursday, itsMay, wearRedShirt);
```

#1,100 – Increment and Decrement Operators Are Not Thread-Safe

If you have multiple threads increment or decrementing a variable using the increment or decrement operators, you may not get the desired result.  These operators are not thread-safe.

Imagine two threads that increment a variable.  If they do the operation serially, the variable ends up correctly incremented twice.  If the two threads read the value at the same time, however, they may both end up writing the same value back to the variable.  The variable ends up incremented just once.

```        private static int counter1 = 0;
private static int counter2 = 0;

static void Main(string[] args)
{
int maxExclusive = 1001;

Parallel.For(1, maxExclusive, n =>
{
// Do some work here.