《C#表达式70》由会员分享,可在线阅读,更多相关《C#表达式70(64页珍藏版)》请在金锄头文库上搜索。
1、表达式 1057.1 表达式的分类 1057.1.1 表达式的值 1067.2 运算符 1067.2.1 运算符的优先级和顺序关联性 1067.2.2 运算符重载 1077.2.3 一元运算符重载决策 1087.2.4 二元运算符重载决策 1097.2.5 候选用户定义运算符 1097.2.6 数值提升 1097.2.6.1 一元数值提升 1107.2.6.2 二元数值提升 1107.3 成员查找 1117.3.1 基类型 1117.4 函数成员 1127.4.1 参数列表 1147.4.2 重载决策 1167.4.2.1 适用函数成员 1167.4.2.2 更好的函数成员 1177.4.2.
2、3 更好的转换 1177.4.3 函数成员调用 1187.4.3.1 已装箱实例上的调用 1197.5 基本表达式 1197.5.1 文本 1207.5.2 简单名称 1207.5.2.1 块中的固定含义 1217.5.3 带括号的表达式 1227.5.4 成员访问 1227.5.4.1 相同的简称和类型名称 1237.5.5 调用表达式 1247.5.5.1 方法调用 1247.5.5.2 委托调用 1257.5.6 元素访问 1257.5.6.1 数组访问 1267.5.6.2 索引器访问 1267.5.7 this 访问 1277.5.8 base 访问 1277.5.9 后缀增量和后缀
3、减量运算符 1287.5.10 new 运算符 1297.5.10.1 对象创建表达式 1297.5.10.2 数组创建表达式 1307.5.10.3 委托创建表达式 1317.5.11 typeof 运算符 1337.5.12 checked 和 unchecked 运算符 1337.6 一元运算符 1367.6.1 一元加运算符 1367.6.2 一元减运算符 1367.6.3 逻辑否定运算符 1377.6.4 按位求补运算符 1377.6.5 前缀增量和减量运算符 1377.6.6 强制转换表达式 1387.7 算术运算符 1397.7.1 乘法运算符 1397.7.2 除法运算符 14
4、07.7.3 余数运算符 1417.7.4 加法运算符 1427.7.5 减法运算符 1447.8 移位运算符 1467.9 关系和类型测试运算符 1477.9.1 整数比较运算符 1477.9.2 浮点比较运算符 1487.9.3 小数比较运算符 1497.9.4 布尔相等运算符 1497.9.5 枚举比较运算符 1497.9.6 引用类型相等运算符 1497.9.7 字符串相等运算符 1517.9.8 委托相等运算符 1517.9.9 is 运算符 1517.9.10 as 运算符 1527.10 逻辑运算符 1527.10.1 整数逻辑运算符 1537.10.2 枚举逻辑运算符 1537
5、.10.3 布尔逻辑运算符 1537.11 条件逻辑运算符 1537.11.1 布尔条件逻辑运算符 1547.11.2 用户定义的条件逻辑运算符 1547.12 条件运算符 1557.13 赋值运算符 1567.13.1 简单赋值 1567.13.2 复合赋值 1587.13.3 事件赋值 1597.14 表达式 1597.15 常量表达式 1597.16 布尔表达式 160表达式表达式是一个运算符和操作数的序列。本章定义语法、操作数和运算符的计算顺序以及表达式的含义。表达式的分类一个表达式可归类为下列类别之一:值。每个值都有关联的类型。变量。每个变量都有关联的类型,称为该变量的已声明类型。命
6、名空间。这类表达式只能出现在 member-access(第 0 节)的左边。在任何其他上下文中,归类为命名空间的表达式将导致编译时错误。类型。这类表达式只能出现在 member-access(第 0 节)的左边,或作为 as 运算符(第 7.9.10 节)、is 运算符(第 7.9.9 节)或 typeof 运算符(第 7.5.11 节)的操作数。在任何其他上下文中,归类为类型的表达式将导致编译时错误。方法组。它是一组重载方法,是成员查找(第 0 节)的结果。方法组可以有关联的实例表达式。当调用实例方法时,实例表达式的计算结果成为由 this(第 0 节)表示的实例。只能在 invocati
7、on-expression(第 0 节)或 delegate-creation-expression(第 7.5.10.3 节)中使用方法组。在任何其他上下文中,归类为方法组的表达式将导致编译时错误。属性访问。每个属性访问都有关联的类型,即该属性的类型。此外,属性访问可以有关联的实例表达式。当调用实例属性访问的访问器(get 或 set 块)时,实例表达式的计算结果成为由 this(第 0 节)表示的实例。事件访问。每个事件访问都有关联的类型,即该事件的类型。此外,事件访问还可以有关联的实例表达式。事件访问可作为 += 和 -= 运算符(第 0)的左操作数出现。在任何其他上下文中,归类为事件访
8、问的表达式将导致编译时错误。索引器访问。每个索引器访问都有关联的类型,即该索引器的元素类型。此外,索引器访问还可以有关联的实例表达式和关联的参数列表。当调用索引器访问的访问器(get 或 set 块)时,实例表达式的计算结果成为由 this(第 0 节)表示的实例,而实参列表的计算结果成为调用的形参列表。Nothing。这出现在当表达式是调用一个具有 void 返回类型的方法时。Nothing 类别的表达式仅在 statement-expression(第 Error! Reference source not found. 节)的上下文中有效。表达式的最终结果绝不会是一个命名空间、类型、方法
9、组或事件访问。恰如以上所述,这些类别的表达式是只能在特定上下文中使用的中间构造。通过执行 get-accessor 或 set-accessor 的调用,属性访问或索引器访问总是被重新归类为值。特定访问器是由属性或索引器访问的上下文确定的:如果访问是赋值的目标,则调用 set-accessor 以赋新值(第 0 节)。否则调用 get-accessor 访问器以获取当前值(第 0 节)。表达式的值大多数含有表达式的构造最后都要求表达式表示一个值 (value)。在此情况下,如果实际的表达式表示命名空间、类型、方法组或 Nothing,则将发生编译时错误。但是,如果表达式表示属性访问、索引器访问
10、或变量,则将它们隐式替换为相应的属性、索引器或变量的值:变量的值只是当前存储在该变量所标识的存储位置的值。在可以获取变量的值之前,变量必须被视为已明确赋值(第 Error! Reference source not found. 节),否则将发生编译时错误。一个属性访问表达式的值通过调用属性的 get-accessor 来获取。如果属性没有 get-accessor,则发生编译时错误。否则将执行一个函数成员调用(第 0 节),调用的结果成为属性访问表达式的值。一个索引器访问表达式的值通过调用索引器的 get-accessor 来获取。如果索引器没有 get-accessor,则发生编译时错误。
11、否则将使用与索引器访问表达式关联的参数列表来执行函数成员调用(第 0 节),调用的结果成为索引器访问表达式的值。运算符表达式由操作数 (operand) 和运算符 (operator) 构成。表达式的运算符指示对操作数进行什么样的运算。运算符的示例包括 +、- 、*、/ 和 new。操作数的示例包括文本 (literal)、字段、局部变量和表达式。有三类运算符:一元运算符。一元运算符带一个操作数并使用前缀表示法(如 x)或后缀表示法(如 x+)。二元运算符。二元运算符带两个操作数并且全都使用中缀表示法(如 x + y)。三元运算符。只有一个三元运算符 ?: 存在,它带三个操作数并使用中缀表示法
12、 (c? x: y)。表达式中运算符的计算顺序由运算符的优先级 (precedence) 和关联性 (associativity)(第 0 节)确定。表达式中的操作数从左到右进行计算。例如,在 F(i) + G(i+) * H(i) 中,F 方法是使用 i 的旧值调用的,然后 G 方法也是使用 i 的旧值进行调用,最后 H 方法使用 i 的新值调用。这与运算符的优先级无关。某些运算符可以重载 (overloaded)。运算符重载允许指定使用用户定义的运算符来执行某些运算,这些运算的操作数中至少有一个,甚至两个都属于用户定义的类或结构类型(第 0 节)。运算符的优先级和顺序关联性当表达式包含多个
13、运算符时,运算符的优先级 (precedence) 控制各运算符的计算顺序。例如,表达式 x + y * z 按 x + (y * z) 计算,因为 * 运算符的优先级比 + 运算符高。运算符的优先级由运算符的关联语法产生式的定义确定。例如,一个 additive-expression 由以 + 或 - 运算符分隔的 multiplicative-expression 组成,因此给 + 和 - 运算符赋予的优先级比 *、/ 和 % 运算符低。下表按照从最高到最低的优先级顺序概括了所有的运算符:章节 类别 运算符0 基本 x.y f(x) ax x+ x- newtypeof checked u
14、nchecked0 一元 + - ! +x -x (T)x0 乘除 * / %0 加减 + -0 移位 0 关系和类型检测 = is as0 相等 = !=0 逻辑 AND &0 逻辑 XOR 0 逻辑 OR |0 条件 AND &0 条件 OR |0 条件 ?:0 赋值 = *= /= %= += -= = &= = |=当操作数出现在具有相同优先级的两个运算符之间时,运算符的顺序关联性控制运算的执行顺序:除了赋值运算符外,所有的二元运算符都向左顺序关联 (left-associative),意思是从左向右执行运算。例如,x + y + z 按 (x + y) + z 计算。赋值运算符和条件
15、运算符 (?:) 向右顺序关联 (right-associative),意思是从右向左执行运算。例如,x = y = z 按 x = (y = z) 计算。优先级和顺序关联性都可以用括号控制。例如,x + y * z 先将 y 乘以 z,然后将结果与 x 相加,而 (x + y) * z 先将 x 与 y 相加,然后再将结果乘以 z。运算符重载所有一元和二元运算符都具有可自动用于任何表达式的预定义实现。除了预定义实现外,还可通过在类或结构(第 Error! Reference source not found. 节)中设置 operator 声明来引入用户定义的实现。用户定义的运算符实现的优先
16、级总是高于预定义运算符实现的优先级:仅当没有适用的用户定义运算符实现存在时,才会考虑预定义的运算符实现,如第 0 节和第 7.2.4 节中所述。可重载的一元运算符 (overloadable unary operator) 有:+ - ! + - true false虽然不在表达式中显式使用 true 和 false(并且因此而未包括在第 0 节的优先级表中),但仍将它们视为运算符,因为它们在多种表达式上下文中被调用:布尔表达式(第 0 节)和涉及条件运算符(第 7.12 节)以及条件逻辑运算符(第 7.11 节)的表达式。可重载的二元运算符 (overloadable binary operator) 有:+ - * / % & | = != = 、= 和 + s + M1 + M2 + M2cd3 = cd1 + cd2 +