1.一元运算符
运算符 | 描述 |
+x | 一元 + 运算符返回其操作数的值。 |
-x | 一元 - 运算符对其操作数的数值取负。 |
++x | ++x 的结果是按 1 递增其操作数后的 x 的值。 |
--x | --x 的结果是按 1 递减其操作数后的 x 的值。 |
x++ | x++ 的结果是按 1 递增其操作数前的 x 的值。 |
x-- | x-- 的结果是按 1 递减其操作数前的 x 的值。 |
2.算术运算符
运算符 | 描述 |
x + y | 加法、字符串连接、委托实例组合 |
x - y | 减法、委托实例移除 |
x * y | 乘法 |
x / y | 除法 |
x % y | 余数 |
3.赋值运算符
运算符 | 描述 |
x = y | 赋值 |
x += y | 加法赋值、订阅事件、字符串连接赋值 |
x -= y | 减法赋值、取消订阅事件 |
x *= y | 乘法赋值 |
x /= y | 除法赋值 |
x %= y | 余数赋值 |
x &= y | 逻辑与赋值、位逻辑与赋值 |
x |= y | 逻辑或赋值、位逻辑或赋值 |
x ^= y | 逻辑异或赋值、位逻辑异或赋值 |
x <<= y | 左移位赋值 |
x >>= y | 右移位赋值 |
=> | lambda 表达式(匿名函数),Expression-bodied表达式 |
= ref | 引用分配给ref局部变量 或 ref readonly局部变量 |
4.比较运算符
运算符 | 名称 | 描述 |
x == y | 相等 | 如果操作数相等,等于运算符 == 返回 true ,否则返回 false 。 |
x != y | 不等 | 如果操作数不相等,不等于运算符 != 返回 true ,否则返回 false 。 |
x < y | 小于 | 如果左侧操作数小于右侧操作数,< 运算符返回 true ,否则返回 false 。 |
x > y | 大于 | 如果左侧操作数大于右侧操作数,> 运算符返回 true ,否则返回 false 。 |
x <= y | 小于或等于 | 如果左侧操作数小于或等于右侧操作数,<= 运算符返回 true ,否则返回 false 。 |
x >= y | 大于或等于 | 如果左侧操作数大于或等于右侧操作数, 运算符返回 true ,否则返回 false 。 |
5.布尔逻辑运算符
&
运算符与 &&
运算符的区别是:如果左侧操作数的计算结果为 true
,&&
运算符才会计算右侧操作数。而 &
运算符 无论左侧操作数的计算结果是 true
或 false
,都会计算右侧操作数。因此, &&
运算符 的性能比 &
运算符 高。x | y
运算符与 x || y
运算符的区别类似。
运算符 | 名称 | 描述 |
!x | 逻辑非 | 如果 x 的计算结果为 false ,则 !x 的结果为 true ,否则,结果为 false 。 |
x & y | 逻辑与 | 如果 x 和 y 的计算结果都为 true ,则 x & y 的结果为 true ,否则,结果为 false 。 |
x | y | 逻辑或 | 如果 x 或 y 的计算结果为 true ,则 x | y 的结果为 true 。 否则,结果为 false 。 |
x ^ y | 逻辑异或 | 如果 x 的计算结果为 true 且 y 的计算结果为 false ,或者 x 的计算结果为 false 且 y 的计算结果为 true ,那么 x ^ y 的结果为 true 。 否则,结果为 false 。 |
x && y | 条件逻辑与(又称“短路逻辑与”) | 同 x & y ,但不支持Nullable类型的操作数。 |
x || y | 条件逻辑或(又称”短路逻辑或”) | 同 x | y ,但不支持Nullable类型的操作数。 |
and | and运算符 | 同 x & y 。例如,>= 3 and < 6 => "spring" 。 |
or | or运算符 | 同 x | y 。例如,12 or (>= 1 and < 3) => "winter" 。 |
布尔逻辑运算符一览表:
x | y | x&y | x|y | x^y | !x |
---|---|---|---|---|---|
true | true | true | true | flase | false |
true | false | false | true | true | false |
true | null | null | true | null | false |
false | true | false | true | true | true |
false | false | false | false | false | true |
false | null | false | null | null | true |
null | true | null | true | null | null |
null | false | false | null | null | null |
null | null | null | null | null | null |
6.按位和移位运算符
运算符 | 名称 | 描述 |
~x | 按位求补 | ~ 运算符通过反转每个位产生其操作数的按位求补。也可以使用 ~ 符号来声明终结器。 |
x & y | 位逻辑与 | & 运算符计算其整型操作数的位逻辑 与。 |
x | y | 位逻辑或 | | 运算符计算其整型操作数的位逻辑 或。 |
x ^ y | 位逻辑异或 | ^ 运算符计算其整型操作数的位逻辑 异或。 |
x << y | 向左移位 | << 运算符将其左侧操作数向左移动右侧操作数定义的位数。 |
x >> y | 向右移位 | >> 运算符将其左侧操作数向右移动右侧操作数定义的位数。 |
7.Null运算符
运算符 | 名称 | 描述 |
a?.x | Null条件运算符 | 如果 a 为非 null ,则 a?.x 的结果将与 a.x 的结果相同。否则,将返回 null 。 |
a?[i] | Null条件运算符 | 如果 a 为非 null ,则 a?[i] 的结果将与 a[x] 的结果相同。否则,将返回 null 。 |
x ?? y | Null合并运算符 | 如果 x 为 null ,则返回值为 y ,否则返回 x 。 |
x ??= y | Null合并赋值运算符 | 如果 x 为 null ,则将 y 赋值给 x ,否则不赋值。 |
x! | Null包容运算符(又称”Null抑制运算符“) | 通过使用 Null包容运算符,可以告知编译器传递 null 是预期行为,不应发出警告。 |
8.三元条件运算符
运算符 | 描述 |
x ? y : z | 如果 x 为 true ,则计算 y ;如果 x 为 false ,则计算 z 。 |
9.::(命名空间运算符)
运算符 | 描述 |
:: | 使用命名空间别名限定符 :: 访问已设置别名的命名空间的成员。:: 限定符左侧标识符必须是命名空间别名。 |
global:: | global 关键字与 :: 限定符表示全局命名空间别名。 |
10.类型测试运算符和强制转换表达式
运算符 | 名称 | 描述 |
typeof(T) | typeof运算符 | typeof 运算符用于获取某个类型的 System.Type 实例。typeof 运算符的实参必须是类型或类型形参的名称,不可以是表达式。 |
nameof(T) | nameof表达式 | nameof 表达式可生成变量、类型或成员的字符串常量名称。例如,Console.WriteLine(nameof(System.Collections.Generic)); // output: Generic |
sizeof(T) | sizeof运算符 | sizeof 运算符返回给定类型的变量所占用的字节数。 |
E is T 或E is T a | is 表达式 | 如果 E 表达式的类型与 T 类型兼容,则返回 true 并将 E 表达式的值赋值给变量 a ;否则,返回 false 。 |
E is not T | is not 表达式 | 如果 E 表达式的类型与 T 类型不兼容,则返回 true ;否则,返回 false 。 比如:result is not null ,input is not (float or double) |
E is { P: value1,F:value2 } | 属性模式 | 比如:static bool IsConferenceDay(DateTime date) => date is { Year: 2020, Month: 5, Day: 19 or 20 or 21 }; |
E as T | as 运算符 | 如果 E 表达式能转换为 T 类型,则返回 类型为 T 的 E ,否则返回 null 。等同于E is T ? (T)(E) : (T)null 。as 运算符仅考虑引用类型、Nullable 、装箱和取消装箱转换,不能使用 as 运算符执行用户定义的转换,为此,请使用强制转换表达式。 |
(T)E | 强制转换表达式(cast expression) | 形式为 (T)E 的强制转换表达式将表达式 E 的结果显式转换为类型 T 。 |
11.new运算符
通用类类型 | 描述 |
new T(); | 使用 构造函数 创建类或委托的对象。 |
new(); | 如果已知表达式的类型,则可以省略类型名称。 |
new T() {...}; | 使用 构造函数 和 对象初始值设定项 创建对象。 |
new() {...}; | 如果已知表达式的类型,则可以省略类型名称并使用 构造函数 和 对象初始值设定项 创建对象。 |
new T {...}; | 不使用 构造函数,使用 对象初始值设定项 创建对象。 |
匿名类型 | 描述 |
new {...}; | 只使用 对象初始值设定项 创建匿名类型的对象。 |
数组类型 | 描述 |
new T[n]; | 声明类型为T ,长度为n 的数组。 |
new T[n] {...}; | 声明类型为T ,长度为n 的数组,并使用数组初始值设定项初始化。 |
new T[] {...}; | 声明类型为T 的数组,并使用数组初始值设定项初始化,长度由初始化推断确定。 |
new[] {...}; | 只使用数组初始值设定项声明并初始化数组,类型和长度由初始化推断确定。 |
12.成员访问运算符和表达式
运算符 | 名称 | 描述 |
a.x | 成员访问表达式 | 用于访问命名空间或类型的成员。 |
f(x) | 调用表达式 | 使用括号 () 调用方法或调用委托。还可以使用括号来调整表达式中计算操作的顺序。 |
a[i] | 数组元素或索引器运算符 | 方括号 [] 通常用于数组、索引器或指针元素访问,还用于指定特性。 |
^n | 从末尾开始索引运算符 | 对于长度为 length 的序列,^n 指向与序列开头偏移 length - n 的元素。例如,^1 指向序列的最后一个元素,^length 指向序列的第一个元素。 |
x..y | 范围运算符 | 左侧操作数是范围的包含性开头,右侧操作数是范围的不包含性末尾。 |
13.默认值表达式
运算符 | 名称 | 描述 |
default(T) | default运算符 | default 运算符的实参必须是类型或类型形参的名称,例如:Console.WriteLine(default(int)); // output: 0 。 |
default | default字面值 | 可以使用 default 文本生成类型的默认值,例如:T initialValue = default 。 |
default: | default标签 | 可以将 default 关键字用作 switch 语句中的默认用例标签。 |
14.switch表达式
可以使用 switch
表达式,将与 方法形参兼容 的 输入表达式 与 =>
运算符左侧的候选表达式进行比较,从而返回第一个匹配的候选表达式右侧的表达式的值。
注意:switch
表达式虽与选择语句里的 switch
语句提供类似的功能,但是两回事。
候选表达式可以是整数、浮点、布尔、字符、字符串、枚举、const常量、null、类型名称、弃元变量、比较表达式、属性表达式等等。
候选表达式可能表现力不够,无法详细描述switch arm计算的条件。在这种情况下,可以附加 case guard,必须与候选表达式同时满足。可以在候选表达式后面的 when
关键字之后指定一个 case guard,case guard 必须是布尔表达式。
返回类型 方法名(形参) => 输入表达式 switch
{
候选表达式1 => 表达式1,
候选表达式2 => 表达式2,
候选表达式3 [when 布尔表达式3] => 表达式3,
候选表达式N [when 布尔表达式N] => 表达式N,
}
15.with表达式
with
表达式使用修改的特定属性和字段与左侧操作数的副本生成新的对象。
with
表达式的左侧操作数可以是记录类型或匿名类型。
var p2 = p1 with { Name = "B", X = 5 };
16.true和false运算符
true
运算符返回 bool
值 true
,以指明其操作数一定为 true
。 false
运算符返回 bool
值 true
,以指明其操作数一定为 false
。
如果某类型定义这两个运算符之一,那它还必须定义另一个运算符。
public static bool operator true(LaunchStatus x) => x == Green || x == Yellow;
public static bool operator false(LaunchStatus x) => x == Red;
17.指针运算符
运算符 | 名称 | 描述 |
&x | address-of运算符 | 用于获取固定变量(驻留在不受垃圾回收器操作影响的存储位置的变量)的地址,可移动变量(驻留在受垃圾回收器影响的存储位置的变量)需使用fixed 语句固定获取地址。& 运算符无法获取常量或值的地址。 |
*x | 指针间接运算符(又称”取消引用运算符“) | 用于获取指针指向的变量,* 运算符的操作数必须是指针类型。 |
x->y | 指针成员访问运算符 | -> 运算符是指针间接运算符和成员访问表达式的合并,等同于(*x).y 。 |
p[n] | 指针元素访问运算符 | 对于指针类型的表达式 p ,p[n] 形式的指针元素访问计算方式为 *(p + n) ,其中 n 必须是可隐式转换为 int 、uint 、long 或 ulong 的类型。 |
p + n | 向指针增加整数值 | p + n 和 n + p 表达式都生成 T* 类型的指针,该指针是将 n * sizeof(T) 添加到 p 给出的地址得到的。 |
p - n | 从指针中减少整数值 | p - n 表达式生成 T* 类型的指针,该指针是从 p 给出的地址中减去 n * sizeof(T) 得到的。 |
p1 - p2 | 指针减法运算符 | 对于类型为 T* 的两个指针 p1 和 p2 ,p1 - p2 计算公式为 ((long)(p1) - (long)(p2)) / sizeof(T) 。 |
++x | 指针递增前缀 | 同一元运算符。 |
--x | 指针递减前缀 | 同一元运算符。 |
x++ | 指针递增后缀 | 同一元运算符。 |
x-- | 指针递减后缀 | 同一元运算符。 |
== | 指针相等 | 同相等运算符。 |
!= | 指针不等 | 同相等运算符。 |
< | 指针小于 | 同比较运算符。 |
> | 指针大于 | 同比较运算符。 |
<= | 指针小于或等于 | 同比较运算符。 |
>= | 指针大于或等于 | 同比较运算符。 |
18.stackalloc表达式
stackalloc
是单词stack(堆栈)和单词allocate(分配)的合并简写,表示在堆栈上分配内存块。
//T必须是非托管类型
//E的计算结果必须为非负int值
stackalloc T[E];
18.1分配给Span<T>或ReadOnlySpan<T>
stackalloc
表达式的结果分配给 Span<T>或 ReadOnlySpan<T> 变量时,不必使用 unsafe 上下文。
建议尽可能使用 Span<T> 或 ReadOnlySpan<T> 类型来处理堆栈中分配的内存。
int length = 3;
Span<int> numbers = stackalloc int[length];
for (var i = 0; i < length; i++)
{
numbers[i] = i;
}
//使用数组初始值设定项语法来定义新分配内存的内容
Span<int> first = stackalloc int[3] { 1, 2, 3 };
Span<int> second = stackalloc int[] { 1, 2, 3 };
ReadOnlySpan<int> third = stackalloc[] { 1, 2, 3 };
18.2分配给指针类型
stackalloc
表达式的结果分配给 指针 变量时,必须使用 unsafe 上下文。
unsafe
{
int length = 3;
int* numbers = stackalloc int[length];
for (var i = 0; i < length; i++)
{
numbers[i] = i;
}
}
原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/csharp/csharplang/7863.html