[Professional C# 7] Operators (操作符)
C# supports the operators listed in the following table:
The checked and unchecked Operators
Consider the following code:
byte b = byte.MaxValue; b++; Console.WriteLine(b);
The byte data type can hold values only in the range 0 to 255. Assigning byte.MaxValue to a byte results in 255.
With 255, all bits of the 8 available bits in the bytes are set: 11111111.
Incrementing this value by one causes an overflow and results in 0.
C# provides the checked and unchecked operators. If you mark a block of code as checked,
the CLR enforces overflow checking, throwing an OverflowException if an overflow occurs.
byte b = 255; checked { b++; } Console.WriteLine(b);
When you try to run this code, you get an error message like this:
System.OverflowException: Arithmetic operation resulted in an overflow.
You can enforce overflow checking for all unmarked code with the Visual Studio project settings Check
for Arithmetic Overflow/Underflow in the Advance Build Settings. You can change this also directly in the csproj project file:
<PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp2.0</TargetFramework> <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow> </PropertyGroup>
If you want to suppress overflow checking, you can mark the code as unchecked:
byte b = 255; unchecked { b++; } Console.WriteLine(b);
In this case, no exception is raised, but you lose data because the byte type cannot hold a value of 256, the overflowing bits are discarded, and your b variable holds a value of zero (0).
Note that unchecked is the default behavior.
Nullable Types and Operators
int? a = null; int? b = a + 4; // b = null int? c = a * 5; // c = null
When comparing nullable types, if only one of the operands is null, the comparison always equates to false.
int? a = null; int? b = -5; if (a >= b) // if a or b is null, this condition is false { Console.WriteLine("a >= b"); } else { Console.WriteLine("a < b"); }
The Null Coalescing Operator
The null coalescing operator is not only important with nullable types but also with reference types.
private MyClass _val; public MyClass Val { get => _val ?? (_val = new MyClass()); }
The Null-Conditional Operator
you can also solve this issue by using the null coalescing operator and defining another result (for example, 0) in case the result of the left side is null:
int age1 = p?.Age ?? 0;
Multiple null-conditional operators can also be combined.
string city = p?.HomeAddress?.City;
You can also use the null-conditional operator with arrays.
int[] arr = null; int x1 = arr?[0] ?? 0;
Operator Precedence and Associativity
The following table shows the order of precedence of the C# operators. The operators at the top of the table
are those with the highest precedence (that is, the ones evaluated first in an expression containing multiple operators).
GROUP | OPERATORS |
Primary | . ?. () [] ?[] x++ x– – new typeof sizeof checked unchecked |
Unary | + —! ˜ ++x ––x and casts |
Multiplication/division | * / % |
Addition/subtraction | + - |
Shift operators | << >> |
Relational | < ><= >= is as |
Comparison | == != |
Bitwise AND | & |
Bitwise XOR | ^ |
Bitwise OR | | |
Logical AND | && |
Logical OR | || |
Null coalescing | ?? |
Conditional-expression operator | ?: |
Assignment and Lambda | = += -= *= /= %= &= |= ^= <<= >>= >>>= => |
An important right associative operator that might be misleading is the conditional-expression operator. The expression
a ? b: c ? d: e
is evaluated as
a = b: (c ? d: e)