C# 编程/运算符
C# 运算符及其优先级与 C 家族的其他语言中的运算符非常相似。
与 C++ 类似,类可以重载大多数运算符,在该运算符的第一个参数是该类实例的上下文中定义或重新定义运算符的行为,但这样做通常为了清晰而被阻止。
以下是 C# 运算符的内置行为。
以下算术运算符作用于数值操作数(下面“表达式”中的 a
和 b
)。
表达式 | 读取 | 元数 | 解释 |
---|---|---|---|
a + b |
a 加 b |
二元 | + 返回其参数的 和。 |
a - b |
a 减 b |
二元 | - 返回其参数之间的 差。 |
a*b |
a 乘 b |
二元 | * 返回其参数的 乘积。 |
a/b |
a 除以 b |
二元 | / 返回其参数的 商。如果两个操作数都是整数,则使用整数除法获得该商(即它会丢弃任何结果余数)。 |
a%b |
a 模 b |
二元 | % 仅对整数参数进行操作。它返回对这些参数进行整数除法的 余数。(参见 模算术。) |
a++ |
a 加加 或 后自增 a |
一元 | ++ 仅对具有左值的参数进行操作。当放置在其参数之后时,它将该参数增加 1 并返回该参数在增加之前的值。 |
++a |
加加 a 或 前自增 a |
一元 | ++ 仅对具有左值的参数进行操作。当放置在其参数之前时,它将该参数增加 1 并返回结果值。 |
a-- |
a 减减 或 后自减 a |
一元 | -- 仅对具有左值的参数进行操作。当放置在其参数之后时,它将该参数减少 1 并返回该参数在减少之前的值。 |
--a |
减减 a 或 前自减 a |
一元 | -- 仅对具有左值的参数进行操作。当放置在其参数之前时,它将该参数减少 1 并返回结果值。 |
以下逻辑运算符作用于布尔值或整型操作数,如所述。
表达式 | 读取 | 元数 | 解释 |
---|---|---|---|
a&b |
a 按位与 b |
二元 | & 评估其两个操作数并返回其结果的 逻辑合取 (“AND”)。如果操作数是整型,则按位执行逻辑合取。 |
a&&b |
a 与 b |
二元 | && 仅对布尔值操作数进行操作。它评估其第一个操作数。如果结果为false,它返回false。否则,它评估并返回第二个操作数的结果。请注意,如果假设评估第二个操作数不会有任何副作用,则结果与 & 运算符执行的逻辑合取相同。这是一个 短路求值 的示例。 |
a | b |
a 按位或 b |
二元 | | 评估其两个操作数并返回其结果的 逻辑析取 (“OR”)。如果操作数是整型,则按位执行逻辑析取。 |
a || b |
a 或 b |
二元 | || 仅对布尔值操作数进行操作。它评估第一个操作数。如果结果为true,它返回true。否则,它评估并返回第二个操作数的结果。请注意,如果假设评估第二个操作数不会有任何副作用,则结果与 | 运算符执行的逻辑析取相同。这是一个 短路求值 的示例。 |
a ^ b |
a 异或 b |
二元 | ^ 返回其结果的 异或 (“XOR”)。如果操作数是整型,则按位执行异或。 |
!a |
非 a |
一元 | ! 仅对布尔值操作数进行操作。它评估其操作数并返回结果的 否定 (“NOT”)。也就是说,如果 a 评估为false,它返回true;如果 a 评估为true,它返回false。 |
~a |
按位非 a |
一元 | ~ 仅对整型操作数进行操作。它评估其操作数并返回结果的按位否定。也就是说,~a 返回一个值,其中每个位都是评估 a 结果的相应位的否定。 |
表达式 | 读取 | 元数 | 解释 |
---|---|---|---|
a << b |
a 左移 b |
二元 | << 运算其操作数并返回结果的第一个参数,左移由第二个参数指定的位数。它丢弃超出其第一个参数大小的移位的最高位,并将新的最低位设置为零。 |
a >> b |
a 右移 b |
二元 | >> 运算其操作数并返回结果的第一个参数,右移由第二个参数指定的位数。它丢弃移位超出其第一个参数大小的最低位,并将新的最高位设置为第一个参数的符号位,或者如果第一个参数是无符号的则设置为零。 |
二元关系运算符 ==
, !=
, <
, >
, <=
, 和 >=
用于关系运算和类型比较。
表达式 | 读取 | 元数 | 解释 |
---|---|---|---|
a == b |
a 等于 b |
二元 | 对于值类型的参数,== 运算符返回true,如果其操作数具有相同的值,否则返回false。对于字符串类型,它返回true,如果字符串的字符序列匹配。但是,对于其他引用类型(从 System.Object 派生的类型),a == b 仅在 a 和 b 引用同一个对象时返回true。 |
a != b |
a 不等于 b |
二元 | != 运算符返回 == 运算符的逻辑否定。因此,如果 a 不等于 b ,它返回true,如果它们相等,它返回false。 |
a < b |
a 小于 b |
二元 | < 运算符对整型类型进行运算。如果 a 小于 b ,它返回true,否则返回false。 |
a > b |
a 大于 b |
二元 | > 运算符对整型类型进行运算。如果 a 大于 b ,它返回true,否则返回false。 |
a <= b |
a 小于或等于 b |
二元 | <= 运算符对整型类型进行运算。如果 a 小于或等于 b ,它返回true,否则返回false。 |
a >= b |
a 大于或等于 b |
二元 | >= 运算符对整型类型进行运算。如果 a 大于或等于 b ,它返回true,否则返回false。 |
最基本的是 =
运算符。不出所料,它将第二个参数的值(或引用)赋值给第一个参数。因此,赋值运算符是二元的,但具有 n 元形式。
(更准确地说,=
运算符要求其第一个(左)参数是一个可以为其赋值的表达式(一个l-value),而其第二个(右)参数是一个可以求值的表达式(一个r-value)。对左边的可赋值表达式和右边的绑定表达式要求是l-value 和 r-value 术语的来源。)
赋值运算符 (=
) 的第一个参数通常是一个变量。当该参数具有值类型时,赋值操作会更改该参数的基础值。当第一个参数是引用类型时,赋值操作会更改引用,因此第一个参数通常只是引用不同的对象,但它最初引用的对象不会更改(除非它可能不再被引用,并且因此可能成为垃圾回收的候选者)。
表达式 | 读取 | 元数 | 解释 |
---|---|---|---|
a = b |
a 等于(或设置为)b |
二元 | = 运算符先计算其第二个参数,然后将结果赋值给(由其第一个参数指示的l-value)。 |
a = b = c |
b 设置为 c ,然后 a 设置为 b |
n 元 | 等效于 a = (b = c) 。当存在连续赋值时,最右边的赋值首先计算,从右到左进行。在本例中,a 和 b 两个变量的值都为 c 。这可以无限期地继续,将相同的r-value 赋值给多个l-value(例如,a = b = c = d = 0; 等效于 a = 0; b = 0; c = 0; d = 0; )。 |
简写赋值运算符将 a = a operator b
的常见赋值操作缩短为 a operator= b
,从而减少了输入量并使语法更简洁。
表达式 | 读取 | 元数 | 解释 |
---|---|---|---|
a += b |
a 加等于(或增加)b |
二元 | 等效于 a = a + b 。 |
a -= b |
a 减等于(或减少)b |
二元 | 等效于 a = a - b 。 |
a *= b |
a 乘等于(或乘以)b |
二元 | 等效于 a = a*b 。 |
a /= b |
a 除等于(或除以)b |
二元 | 等效于 a = a/b 。 |
a %= b |
a 取模等于 b |
二元 | 等效于 a = a%b 。 |
a &= b |
a 与等于 b |
二元 | 等效于 a = a&b 。 |
a |= b |
a 或等于 b |
二元 | 等效于 a = a|b 。 |
a ^= b |
a 异或等于 b |
二元 | 等效于 a = a^b 。 |
a <<= b |
a 左移赋值 b |
二元 | 等效于 a = a << b 。 |
a >>= b |
a 右移赋值 b |
二元 | 等效于 a = a >> b 。 |
类型信息
[edit | edit source]表达式 | 读取 | 元数 | 解释 |
---|---|---|---|
x is T |
判断 x 是否类型 T |
二元 | 如果基类类型的变量 x 存储了派生类类型 T 的对象,或者 x 是类型 T ,则返回 true;否则返回 false。 |
x as T |
将 x 强制转换为 T |
二元 | 如果基类类型的变量 x 存储了派生类类型 T 的对象,或者 x 是类型 T ,则返回 (T)x (x 强制转换为 T);否则返回 null。等效于 x is T ? (T)x : null |
sizeof(x) |
大小 x |
一元 | 返回值类型 x 的大小。备注:sizeof 运算符只能应用于值类型,不能应用于引用类型。 |
typeof(T) |
类型 T |
一元 | 返回一个 System.Type 对象,描述该类型。 T 必须是类型的名称,而不是变量。使用 GetType 方法来检索变量的运行时类型信息。 |
指针操作
[edit | edit source]注意:大多数 C# 开发人员一致认为,在 C# 中不建议直接操作和使用指针。该语言有许多内置类,可以让你执行几乎任何操作。C# 是为内存管理而构建的,指针的创建和使用极大地破坏了这一目的。这指的是指针的声明以及指针表示法的使用,而不是数组。实际上,只有在“不安全模式”下编译程序,才能使用指针。
表达式 | 读取 | 元数 | 解释 |
---|---|---|---|
*a |
指向 a 的对象 |
一元 | 间接寻址 运算符。允许访问被指向的对象。 |
a->member |
成员 member 属于 a |
二元 | 类似于 . 运算符。允许访问被指向的类和结构体的成员。 |
a[b] |
指向 a 的偏移量 b 处的对象 |
二元 | 用于索引指针。 |
&a |
指向 a 的引用 |
一元 | 引用指针的地址。 |
stackalloc a |
在栈上 a |
二元 | 在栈上分配内存,而不是在堆上。参见 C Sharp Programming/Keywords/stackalloc。 |
fixed a |
阻止 a 被重新分配 |
二元 | 暂时固定一个变量,以便可以找到它的地址。参见 C Sharp Programming/Keywords/fixed。 |
溢出异常控制
[edit | edit source]表达式 | 读取 | 元数 | 解释 |
---|---|---|---|
checked(a) |
计算 a 并检查溢出 |
一元 | 对值 a 使用溢出检查。参见 C Sharp Programming/Keywords/checked。 |
unchecked(a) |
计算 a 而不检查溢出 |
一元 | 避免对值 a 进行溢出检查。参见 C Sharp Programming/Keywords/unchecked。 |
其他
[edit | edit source]表达式 | 读取 | 元数 | 解释 |
---|---|---|---|
a.b |
成员 b 属于 a |
二元 | 访问类型或命名空间 a 的成员 b 。如果 b 是一个字段,它将调用该字段的 get 函数。 |
a[b] |
项 b 位于 a 中 |
二元 | 返回 a 中索引 b 的值。数组使用 0 起始索引。 |
(a)b |
将 b 强制转换为类型 a |
二元 | 显式地将值 b 强制转换为类型 a 。类型 b 必须有一个强制转换函数,可以将它直接强制转换为 a 或另一个具有强制转换函数的类型,该函数可以强制转换为 a 。 |
new a |
创建一个新的 a |
n 元 | 创建一个类型为 a 的对象并调用它的默认构造函数。类型 a 可能包含带有参数的构造函数,在这种情况下,它将采用以下形式 new a(type1 arg1, type2 arg2, ...) 。参见 C Sharp Programming/Keywords/new。 |
a + b |
将字符串 b 连接到字符串 a 的末尾 |
二元 | 如果 a 和 b 是字符串,则将 a 和 b 连接起来。如果任何一个被加数是 null ,则使用空字符串 ("" ) 代替。如果一个被加数是字符串,而另一个是非字符串对象,则在连接之前,将对该对象调用 ToString() 。 |
a + b |
将委托 b 连接到委托 a |
二元 | 如果 a 和 b 是委托,则执行委托连接。 |
a ? b : c |
如果 a 则 b 否则 c |
三元运算符 | 如果 a 为真,则计算并返回 b 的值,否则计算并返回 c 的值。 b 和 c 中只有一个会被计算。 |
a ?? b |
如果 a 是 null 则 b 否则 a |
二元 | 如果 a 为 null ,则计算并返回 b 的值,否则计算并返回 a 的值。 如果 a 不为 null ,则不会计算 b 。 |
a?.b |
如果 a 不为 null 则计算 b |
二元 | 这在尝试引用成员字段或方法之前判断对象是否为 null 。 三元运算符与 ?? 结合使用以提供备选方案(例如 a?.b()??c )。 可以与 ?[] 结合使用,以实现 n 元形式,并进行连续的空值检查(例如,a?.b()?[c] )。 (从 C# 6 开始可用) |
a?[b] |
如果 a 不为 null 则获取 b |
二元 | 这在尝试引用项目(数字或标识符)之前判断数组或其他结构是否为 null 。 三元运算符与 ?? 结合使用以提供备选方案(例如 a?[b]??c )。 可以与 ?. 结合使用,以实现 n 元形式,并进行连续的空值检查(例如,a?.b()?[c] )。 (从 C# 6 开始可用) |
@"a" |
逐字 "a" |
零元 | 逐字文本的字符串常量,即忽略转义字符。 |
$"{b}" |
将 b 插入字符串字面量中 |
n 元 | $ 开始字符串插值语句,该语句将子字符串插入到字符串字面量中,这对于快速构建字符串非常有用。 {} 中包含的符号名称将被计算为字符串值,必要时使用 ToString() 。 (从 C# 6 开始可用) |
$@"{b}" |
将 b 插入逐字字符串字面量中 |
n 元 | 结合了 @ 和 $ 的功能。 大括号字面量可以使用 {{ 和 }} 指定 (从 C# 6 开始可用。注意:在 C# 8 及更高版本中,运算符的顺序可以互换。) |