虽然语句是C#程序的构造块,但任何一条符合语法C#语句离不开表达式。
“表达式”是由一个或多个操作数以及零个或零个以上的运算符所组成的序列,可以通过计算得到一个值、对象、方法或命名空间等结果。表达式可以包含文本值、方法调用、运算符及其操作数,或简单名称。简单名称可以是变量、类型成员、方法参数、命名空间或类型的名称。
表达式可以使用运算符,而运算符又可以将其他表达式用作参数,或者使用方法调用,而方法调用的参数又可以是其他方法调用,因此表达式既可以非常简单,也可以非常复杂。下面是表达式的两个示例:
在大部分使用表达式的上下文中,例如在语句或方法参数中,表达式应计算为某个值。如果 x 和 y 是整数,表达式 x + y 将计算为一个数值。 表达式 new MyClass() 计算为对 MyClass 对象的新实例的引用。 表达式 myClass.ToString() 计算为一个字符串,因为字符串是该方法的返回类型。 然而,虽然命名空间名称归类为表达式,但它不计算为值,因此永远不能作为任何表达式的最终结果。命名空间名称不能传递给方法参数,不能用在新表达式中,也不能赋值给变量。命名空间名称只能用作较大表达式的子表达式。同样如此的还有类型(与 System . Type 对象不同)、方法组名称(与特定方法不同)以及事件 add 和 remove 访问器。
如果值大于值类型的最大值,数值表达式可能导致溢出。
在 C# 中,“运算符”是一个术语或符号,它接受一个或多个表达式(即“操作数”)作为输入并返回值。接受一个操作数的运算符称为“一元”运算符,例如增量运算符 ( ++) 或 new。 接受两个操作数的运算符称为“二元”运算符,例如算术运算符 +、 -、 *、 /。 条件运算符 ?: 接受三个操作数,是 C# 中唯一的三元运算符。
下面的 C# 语句包含一个一元运算符和一个操作数。增量运算符 ++ 修改操作数 y 的值:
下面的 C# 语句包含两个二元运算符,它们分别有两个操作数。赋值运算符 = 将一个整数 y 和一个表达式 2 + 3 作为操作数。 表达式 2 + 3 本身包含加运算符,并使用整数值 2 和 3 作为操作数:
操作数可以是任何大小的有效表达式,可由任何数量的其他操作组成。在计算表达式时,编译器首先从左向右计算所有操作数。计算完所有操作数之后,按照称为“运算符优先级”的特定顺序计算运算符。下表根据运算符执行的操作类型将它们划分到不同的类别中。类别按优先级顺序列出。
主要运算符:
表达式 | 说明 |
---|---|
x .y | 成员访问 |
f (x) | 方法和委托调用 |
a [x] | 数组和索引器访问 |
x ++ | 后递增 |
x -- | 后递减 |
new T(...) | 对象和委托创建 |
new T(...){...} | 具有初始值设定项的对象创建。 |
new {...} | 匿名对象初始值设定项。 |
new T[...] | 数组创建。 |
typeof(T) | 获取 T 的 System.Type 对象 |
checked(x) | 在已检查的上下文中计算表达式 |
unchecked(x) | 在未检查的上下文中计算表达式 |
default (T) | 获取类型 T 的默认值 |
delegate {} | 匿名函数(匿名方法) |
一元运算符
乘法运算符
加法运算符
移位运算符
关系和类型运算符
表达式 | 说明 |
---|---|
x < y | 小于 |
x > y | 大于 |
x <= y | 小于或等于 |
x >= y | 大于或等于 |
x is T | 如果 x 为 T,则返回 True;否则返回 False。 |
x as T | 返回类型为 T 的 x,如果 x 不是 T,则返回 null |
相等运算符
赋值和匿名运算符
表达式 | 说明 |
---|---|
赋值 | |
x op= y | |
(T x) => y | 匿名函数(lambda 表达式) |
逻辑、条件和 null 运算符
类别 | 表达式 | 说明 |
---|---|---|
逻辑“与” | x & y | 整型按位“与”,布尔型逻辑“与” |
逻辑“异或” | x ^ y | 整型按位“异或”,布尔型逻辑“异或” |
逻辑“或” | x| y | 整型按位“或”,布尔型逻辑“或” |
条件“与” | x && y | 仅当 x 为 True 时计算 y |
条件“或” | x || y | 仅当 x 为 False 时计算 y |
Null 合并 | X ??y | 如果 x 为 Null 则计算结果为 y,否则计算结果为 x |
条件 | x ?: y : z | 如果 x 为 True 则计算结果为 y,如果 x 为 False 则计算结果为 z |
当表达式中出现两个具有相同优先级的运算符时,将根据结合性计算它们。左结合运算符按从左到右的顺序计算。例如, x * y / z 计算为 (x * y) / z。 右结合运算符按从右到左的顺序计算。赋值运算符和三元运算符 ( ?:) 是右结合运算符。 其他所有二元运算符都是左结合运算符。
可以将表达式用括号括起来强制在计算其他任何表达式之前计算该表达式。例如, 2 + 3 * 2 通常将为 8。 这是因为乘法运算符的优先级高于加法运算符。将该表达式写为 (2 + 3) * 2 的形式,结果将是 10,因为它指示 C# 编译器必须在计算乘法运算符 * 之前计算加法运算符 +。
对于自定义的类和结构,您可以更改运算符的行为。此过程称为“运算符重载”。