![C# 10核心技术指南](https://wfqqreader-1252317822.image.myqcloud.com/cover/89/52513089/b_52513089.jpg)
2.9 表达式和运算符
表达式本质上是值,最简单的表达式是常量和变量。表达式能够用运算符进行转换和组合,运算符用一个或多个输入操作数来输出一个新的表达式。
以下是一个常量表达式的例子:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0088-05.jpg?sign=1739339923-4DJe1aZG2tgNDd5f7rp5lGhcgriuMfrZ-0-205496817bdcaeb01f66ca493f4a74bc)
可以使用*运算符来组合两个操作数(字面量表达式12和30):
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0088-06.jpg?sign=1739339923-p5Gng7AyEOsUH2s9rH997w0PHmfcjmJe-0-59e634b22303648fd1662c075f34bdfb)
由于操作数本身可以是表达式,所以可以创造出更复杂的表达式。例如,(12 * 30)是下面的表达式中的操作数:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0088-07.jpg?sign=1739339923-HazCPzkmzr3bCAeejIenuvKJ8GTBI3AW-0-5f30793e9441b2c7c3d7e3a53f4296ae)
C#中的运算符分为一元运算符、二元运算符和三元运算符,这取决于它们使用的操作数数量(1、2或3)。二元运算符总是使用中缀表示法,即运算符在两个操作数之间。
2.9.1 基础表达式
基础表达式由C#语言内置的基础运算符表达式组成,例如:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0089-01.jpg?sign=1739339923-uiAQkZSeuheZBr5GCxtJzA7FT3yE3i2G-0-b152792497e4e7a1eb7a0f7c1f60fe1e)
这个表达式由两个基础表达式构成,第一个表达式执行成员查找(用.运算符),而第二个表达式执行方法调用(用()运算符)。
2.9.2 空表达式
空表达式(void expression)是没有值的表达式,例如:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0089-02.jpg?sign=1739339923-M9cbjSg8AG9q3paB5VTHpR4GuoIYMWC7-0-bd3987d2a16ae9d1247b658dfad698cc)
因为空表达式没有值,所以不能作为操作数来创建更复杂的表达式:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0089-03.jpg?sign=1739339923-EHFFNuTAZqLGtecQ5lxVJawSUYqiCHdA-0-0819df14339fd971916f666ddef4acba)
2.9.3 赋值表达式
赋值表达式用=运算符将另一个表达式的值赋值给变量,例如:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0089-04.jpg?sign=1739339923-BBWphT4soSCtKhftbbiq7ygk75Y37uxH-0-fb83709c09148bd7636a6702b08c536b)
赋值表达式不是一个空表达式,它的值即是被赋予的值。因此赋值表达式可以和其他表达式组合。下面的例子中,表达式将2赋给x并将10赋给y:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0089-05.jpg?sign=1739339923-UwOjn0363MC4EdZsuAFiLNI3N7V51UNp-0-c6dc90e2d84f934a25fcdf70d332ea9b)
这种类型的表达式也可以用于初始化多个值:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0089-06.jpg?sign=1739339923-E9SZGq9Q26D4CWmZAmHJnbEkUQZVsQDq-0-e1bd0a73844b93cf06c5e44e851d6e63)
复合赋值运算符是由其他运算符组合而成的简化运算符:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0089-07.jpg?sign=1739339923-TqUEtE9h5Wf5aQjYqhvPPMqTBzQUBlth-0-0360729c3760a27babe24a8a664ceccf)
(这条规则的例外是第4章中介绍的事件。事件的+=和-=运算符会进行特殊处理并映射到事件的add和remove访问器上。)
2.9.4 运算符优先级和结合性
当表达式包含多个运算符时,运算符的优先级和结合性决定了计算的顺序。优先级高的运算符先于优先级低的运算符执行。如果运算符的优先级相同,那么运算符的结合性决定计算的顺序。
2.9.4.1 优先级
以下表达式中
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0090-01.jpg?sign=1739339923-riTKJJv0kehMzvfNpQSSHuBlNZUqUkHS-0-25021985d2234e007a1230411db10db3)
由于*的优先级高于+,因此它将按下面的方式计算:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0090-02.jpg?sign=1739339923-c3GrdzjkBy5TdjZad1AypSmQwNnsViCs-0-848304045e2b80a1932fc3abe806c0ed)
2.9.4.2 左结合运算符
二元运算符(除了赋值运算符、Lambda运算符、null合并运算符)是左结合运算符,即它们是从左往右计算的。例如,下面的表达式:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0090-03.jpg?sign=1739339923-d8RgjjimKHycaAJISYSEreiujPjkd735-0-f0b7c84ed43f6cf0a4f17cf821913025)
由于左结合性将按如下的方式计算:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0090-04.jpg?sign=1739339923-Hpn7N5Laa1eacROTVhlcPsFUJB4QIL96-0-33c42b2ccee11db21e7f32661b733206)
插入括号可以改变实际的计算顺序:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0090-05.jpg?sign=1739339923-IfsPQwGahpk3UDWBk3BKgzqEVpWtvaBf-0-f4eb7dc60239e824a6b5e71d2df7210f)
2.9.4.3 右结合运算符
赋值运算符、Lambda运算符、null合并运算符和条件运算符是右结合的。换句话说,它们是从右往左计算。右结合性允许多重赋值,例如:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0090-06.jpg?sign=1739339923-0miqBwY12o1Mgo5xOtcBEobeA0CJ5lde-0-4d4d6dfbe267ef2208d455dad1d6a603)
首先将3赋值给y,之后再将表达式(3)的结果赋值给x。
2.9.5 运算符表
表2-3按照优先级列出了C#的运算符,同一类别的运算符的优先级相同,我们将在4.17节介绍用户可重载的运算符。
表2-3:C#的运算符(按照优先级顺序分类)
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0090-07.jpg?sign=1739339923-vefPlATwyTHQu0qOrqr9S1wAEcJzSx7F-0-16844c65d61c0aa4109ce3a7b868da17)
表2-3:C#的运算符(按照优先级顺序分类)(续)
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0091-01.jpg?sign=1739339923-euVGXeA5e5DkVOfnHiCUTBrdKMv44Tpo-0-e33f41aa03df9555ddd1aa529914a21d)
表2-3:C#的运算符(按照优先级顺序分类)(续)
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0092-01.jpg?sign=1739339923-lVcpipMSrGAvYYkBdNUdmxecnLokLwcu-0-b08140de690992ff569aaaf5eb4f3569)