
2.9 表达式和运算符
表达式本质上是值,最简单的表达式是常量和变量。表达式能够用运算符进行转换和组合,运算符用一个或多个输入操作数来输出一个新的表达式。
以下是一个常量表达式的例子:

可以使用*运算符来组合两个操作数(字面量表达式12和30):

由于操作数本身可以是表达式,所以可以创造出更复杂的表达式。例如,(12 * 30)是下面的表达式中的操作数:

C#中的运算符分为一元运算符、二元运算符和三元运算符,这取决于它们使用的操作数数量(1、2或3)。二元运算符总是使用中缀表示法,即运算符在两个操作数之间。
2.9.1 基础表达式
基础表达式由C#语言内置的基础运算符表达式组成,例如:

这个表达式由两个基础表达式构成,第一个表达式执行成员查找(用.运算符),而第二个表达式执行方法调用(用()运算符)。
2.9.2 空表达式
空表达式(void expression)是没有值的表达式,例如:

因为空表达式没有值,所以不能作为操作数来创建更复杂的表达式:

2.9.3 赋值表达式
赋值表达式用=运算符将另一个表达式的值赋值给变量,例如:

赋值表达式不是一个空表达式,它的值即是被赋予的值。因此赋值表达式可以和其他表达式组合。下面的例子中,表达式将2赋给x并将10赋给y:

这种类型的表达式也可以用于初始化多个值:

复合赋值运算符是由其他运算符组合而成的简化运算符:

(这条规则的例外是第4章中介绍的事件。事件的+=和-=运算符会进行特殊处理并映射到事件的add和remove访问器上。)
2.9.4 运算符优先级和结合性
当表达式包含多个运算符时,运算符的优先级和结合性决定了计算的顺序。优先级高的运算符先于优先级低的运算符执行。如果运算符的优先级相同,那么运算符的结合性决定计算的顺序。
2.9.4.1 优先级
以下表达式中

由于*的优先级高于+,因此它将按下面的方式计算:

2.9.4.2 左结合运算符
二元运算符(除了赋值运算符、Lambda运算符、null合并运算符)是左结合运算符,即它们是从左往右计算的。例如,下面的表达式:

由于左结合性将按如下的方式计算:

插入括号可以改变实际的计算顺序:

2.9.4.3 右结合运算符
赋值运算符、Lambda运算符、null合并运算符和条件运算符是右结合的。换句话说,它们是从右往左计算。右结合性允许多重赋值,例如:

首先将3赋值给y,之后再将表达式(3)的结果赋值给x。
2.9.5 运算符表
表2-3按照优先级列出了C#的运算符,同一类别的运算符的优先级相同,我们将在4.17节介绍用户可重载的运算符。
表2-3:C#的运算符(按照优先级顺序分类)

表2-3:C#的运算符(按照优先级顺序分类)(续)

表2-3:C#的运算符(按照优先级顺序分类)(续)
