# C# Operators

**Visual Studio 2015**

C# provides many operators, which are symbols that specify which operations (math, indexing, function call, etc.) to perform in an expression. You can overload many operators to change their meaning when applied to a user-defined type.

Operations on integral types (such as **==**, **!=**, **<**, **>**, **&**, **|**) are generally allowed on enumeration (**enum**) types.

The sections lists the C# operators starting with the highest precedence to the lowest. The operators within each section share the same precedence level.

These are the highest precedence operators. NOTE, you can click on the operators to go the detailed pages with examples.

x.y – member access.

x?.y – null conditional member access. Returns null if the left hand operand is null.

f(x) – function invocation.

a[x] – aggregate object indexing.

a?[x] – null conditional indexing. Returns null if the left hand operand is null.

x++ – postfix increment. Returns the value of x and then updates the storage location with the value of x that is one greater (typically adds the integer 1).

x-- – postfix decrement. Returns the value of x and then updates the storage location with the value of x that is one less (typically subtracts the integer 1).

New – type instantiation.

Typeof – returns the System.Type object representing the operand.

Checked – enables overflow checking for integer operations.

Unchecked – disables overflow checking for integer operations. This is the default compiler behavior.

default(T) – returns the default initialized value of type T, null for reference types, zero for numeric types, and zero/null filled in members for struct types.

Delegate – declares and returns a delegate instance.

Sizeof – returns the size in bytes of the type operand.

-> – pointer dereferencing combined with member access.

These operators have higher precedence than the next section and lower precedence than the previous section. NOTE, you can click on the operators to go the detailed pages with examples.

+x – returns the value of x.

-x – numeric negation.

!x – logical negation.

~x – bitwise complement.

++x – prefix increment. Returns the value of x after updating the storage location with the value of x that is one greater (typically adds the integer 1).

--x – prefix decrement. Returns the value of x after updating the storage location with the value of x that is one less (typically adds the integer 1).

(T)x – type casting.

Await – awaits a Task.

&x – address of.

*x – dereferencing.

These operators have higher precedence than the next section and lower precedence than the previous section. NOTE, you can click on the operators to go the detailed pages with examples.

x * y – multiplication.

x / y – division. If the operands are integers, the result is an integer truncated toward zero (for example, -7 / 2 is -3).

x % y – modulus. If the operands are integers, this returns the remainder of dividing x by y. If q = x / y and r = x % y, then x = q * y + r.

These operators have higher precedence than the next section and lower precedence than the previous section. NOTE, you can click on the operators to go the detailed pages with examples.

x << y – shift bits left and fill with zero on the right.

x >> y – shift bits right. If the left operand is **int** or **long**, then left bits are filled with the sign bit. If the left operand is **uint** or **ulong**, then left bits are filled with zero.

x < y – less than (true if x is less than y).

x > y – greater than (true if x is greater than y).

x <= y – less than or equal to.

x >= y – less than or equal to.

Is – type compatibility. Returns true if the evaluated left operand can be cast to the type specified in the right operand (a static type).

As – type conversion. Returns the left operand cast to the type specified by the right operand (a static type), but **as** returns **null** where (T)x would throw an exception.

x == y – equality. By default, for reference types other than **string**, this returns reference equality (identity test). However, types can overload **==**, so if your intent is to test identity, it is best to use the ReferenceEquals method on **object**.

x != y – not equal. See comment for **==**. If a type overloads **==**, then it must overload **!=**.

This operator has higher precedence than the next section and lower precedence than the previous section. NOTE, you can click on the operator to go the details page with examples.

x & y – logical or bitwise AND. Use with integer types and **enum** types is generally allowed.

This operator has higher precedence than the next section and lower precedence than the previous section. NOTE, you can click on the operator to go the details page with examples.

x ^ y – logical or bitwise XOR. You can generally use this with integer types and **enum** types.

This operator has higher precedence than the next section and lower precedence than the previous section. NOTE, you can click on the operator to go the details page with examples.

x | y – logical or bitwise OR. Use with integer types and **enum** types is generally allowed.

x && y – logical AND. If the first operand is false, then C# does not evaluate the second operand.

x || y – logical OR. If the first operand is true, then C# does not evaluate the second operand.

x ?? y – returns x if it is non-**null**; otherwise, returns y.

t ? x : y – if test t is true, then evaluate and return x; otherwise, evaluate and return y.

x = y – assignment.

x += y – increment. Add the value of y to the value of x, store the result in x, and return the new value. If x designates an **event**, then y must be an appropriate function that C# adds as an event handler.

x -= y – decrement. Subtract the value of y from the value of x, store the result in x, and return the new value. If x designates an **event**, then y must be an appropriate function that C# removes as an event handler

x *= y – multiplication assignment. Multiply the value of y to the value of x, store the result in x, and return the new value.

x /= y – division assignment. Divide the value of x by the value of y, store the result in x, and return the new value.

x %= y – modulus assignment. Divide the value of x by the value of y, store the remainder in x, and return the new value.

x &= y – AND assignment. AND the value of y with the value of x, store the result in x, and return the new value.

x |= y – OR assignment. OR the value of y with the value of x, store the result in x, and return the new value.

x ^= y – XOR assignment. XOR the value of y with the value of x, store the result in x, and return the new value.

x <<= y – left-shift assignment. Shift the value of x left by y places, store the result in x, and return the new value.

x >>= y – right-shift assignment. Shift the value of x right by y places, store the result in x, and return the new value.

=> – lambda declaration.

The arithmetic operators (+, -, *, /) can produce results that are outside the range of possible values for the numeric type involved. You should refer to the section on a particular operator for details, but in general:

Integer arithmetic overflow either throws an OverflowException or discards the most significant bits of the result. Integer division by zero always throws a

**DivideByZeroException**.Floating-point arithmetic overflow or division by zero never throws an exception, because floating-point types are based on IEEE 754 and so have provisions for representing infinity and NaN (Not a Number).

Decimal arithmetic overflow always throws an OverflowException. Decimal division by zero always throws a DivideByZeroException.

When integer overflow occurs, what happens depends on the execution context, which can be checked or unchecked. In a checked context, an OverflowException is thrown. In an unchecked context, the most significant bits of the result are discarded and execution continues. Thus, C# gives you the choice of handling or ignoring overflow.

In addition to the arithmetic operators, integral-type to integral-type casts can cause overflow, for example, casting a long to an int, and are subject to checked or unchecked execution. However, bitwise operators and shift operators never cause overflow.