Expressions and Operators

An expression essentially denotes a value. The simplest kinds of expressions are constants (such as 123) and variables (such as x). Expressions can be transformed and combined using operators. An operator takes one or more input operands to output a new expression:

12 * 30   // * is an operator; 12 and 30 are operands.

Complex expressions can be built because an operand may itself be an expression, such as the operand (12 * 30) in the following example:

1 + (12 * 30)

Operators in C# can be classed as unary, binary, or ternary—depending on the number of operands they work on (one, two, or three). The binary operators always use infix notation, where the operator is placed between the two operands.

Operators that are intrinsic to the basic plumbing of the language are called primary; an example is the method call operator. An expression that has no value is called a void expression:

Console.WriteLine (1)

Since a void expression has no value, it cannot be used as an operand to build more complex expressions:

1 + Console.WriteLine (1)      // Compile-time error

Assignment Expressions

An assignment expression uses the = operator to assign the result of another expression to a variable. For example:

x = x * 5

An assignment expression is not a void expression. It actually carries the assignment value, and so can be incorporated into another expression. In the following example, the expression assigns 2 to x and 10 to y:

y = 5 * (x = 2)

This style of expression can be used to initialize multiple values:

a = b = c = d = 0

The compound assignment operators are syntactic shortcuts that combine assignment with another operator. For example:

x *= 2    // equivalent to x = x * 2
x <<= 1   // equivalent to x = x << 1

(A subtle exception to this rule is with events, which we describe later: the += and -= operators here are treated specially and map to the event’s add and remove accessors.)

Operator Precedence and Associativity

When an expression contains multiple operators, precedence and associativity determine the order of their evaluation. Operators with higher precedence execute before operators of lower precedence. If the operators have the same precedence, the operator’s associativity determines the order of evaluation.

Precedence

The expression 1 + 2 * 3 is evaluated as 1 + (2 * 3) because * has a higher precedence than +.

Left-associative operators

Binary operators (except for assignment, lambda, and null coalescing operators) are left-associative; in other words, they are evaluated from left to right. For example, the expression 8/4/2 is evaluated as (8/4)/2 due to left associativity. Of course, you can insert your own parentheses to change evaluation order.

Right-associative operators

The assignment and lambda operators, null coalescing operator, and (ternary) conditional operator are right-associative; in other words, they are evaluated from right to left. Right associativity allows multiple assignments such as x=y=3 to compile: it works by first assigning 3 to y, and then assigning the result of that expression (3) to x.

Operator Table

The following table lists C#’s operators in order of precedence. Operators listed under the same subheading have the same precedence. We explain user-overloadable operators in the section Operator Overloading.

Operator symbol

Operator name

Example

Overloadable

Primary (highest precedence)

.

Member access

x.y

No

->

Pointer to struct (unsafe)

x->y

No

()

Function call

x()

No

[]

Array/index

a[x]

Via indexer

++

Post-increment

x++

Yes

--

Post-decrement

x--

Yes

new

Create instance

new Foo()

No

stackalloc

Unsafe stack allocation

stackalloc(10)

No

typeof

Get type from identifier

typeof(int)

No

checked

Integral overflow check on

checked(x)

No

unchecked

Integral overflow check off

unchecked(x)

No

default

Default value

default(char)

No

await

Await

await mytask

No

Unary

sizeof

Get size of struct

sizeof(int)

No

+

Positive value of

+x

Yes

-

Negative value of

-x

Yes

!

Not

!x

Yes

~

Bitwise complement

~x

Yes

++

Pre-increment

++x

Yes

--

Post-increment

--x

Yes

()

Cast

(int)x

No

*

Value at address (unsafe)

*x

No

&

Address of value (unsafe)

&x

No

Multiplicative

*

Multiply

x * y

Yes

/

Divide

x / y

Yes

%

Remainder

x % y

Yes

Additive

+

Add

x + y

Yes

-

Subtract

x - y

Yes

Shift

<<

Shift left

x << 1

Yes

>>

Shift right

x >> 1

Yes

Relational

<

Less than

x < y

Yes

>

Greater than

x > y

Yes

<=

Less than or equal to

x <= y

Yes

>=

Greater than or equal to

x >= y

Yes

is

Type is or is subclass of

x is y

No

as

Type conversion

x as y

No

Equality

==

Equals

x == y

Yes

!=

Not equals

x != y

Yes

Logical And

&

And

x & y

Yes

Logical Xor

^

Exclusive Or

x ^ y

Yes

Logical Or

|

Or

x | y

Yes

Conditional And

&&

Conditional And

x && y

Via &

Conditional Or

||

Conditional Or

x || y

Via |

Conditional (Ternary)

? :

Conditional

isTrue ? thenThis : elseThis

No

Assignment and lambda (lowest precedence)

=

Assign

x = y

No

*=

Multiply self by

x *= 2

Via *

/=

Divide self by

x /= 2

Via /

+=

Add to self

x += 2

Via +

-=

Subtract from self

x -= 2

Via -

<<=

Shift self left by

x <<= 2

Via <<

>>=

Shift self right by

x >>= 2

Via >>

&=

And self by

x &= 2

Via &

^=

Exclusive-Or self by

x ^= 2

Via ^

|=

Or self by

x |= 2

Via |

=>

Lambda

x => x + 1

No

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.225.57.126