这是本文档旧的修订版!
C# 常用运算符大全
C# 提供了丰富的运算符来处理算术、逻辑、位运算以及对象类型操作。除了处理 Null 值的 `?` 和 `??`,以下是其他核心运算符的详细分类讲解。
1. 算术运算符 (Arithmetic Operators)
用于执行基本的数学运算。
| 运算符 | 描述 | 示例 |
|---|---|---|
| `+` | 加法 (也用于字符串拼接) | `x + y` 或 `“Hello” + “ World”` |
| `-` | 减法 | `x - y` |
| `*` | 乘法 | `x * y` |
| `/` | 除法 (整数相除会截断小数) | `10 / 3` 结果为 `3` |
| `%` | 取模 (求余数) | `10 % 3` 结果为 `1` |
| `++` | 自增 (前缀或后缀) | `x++` (先用后加) / `++x` (先加后用) |
| `–` | 自减 (前缀或后缀) | `x–` / `–x` |
int a = 10; int b = 3; Console.WriteLine(a / b); // 输出 3 (整数除法) Console.WriteLine(a % b); // 输出 1 (余数) Console.WriteLine(a + " is number"); // 字符串拼接
2. 逻辑运算符 (Logical Operators)
主要用于布尔 (`bool`) 逻辑判断,常用于 `if` 或 `while` 语句中。
| 运算符 | 名称 | 描述 | ||
|---|---|---|---|---|
| `&&` | 逻辑与 (AND) | 只有两边都为真,结果才为真。短路特性:如果左边为假,右边不再执行。 | ||
| ` | ` | 逻辑或 (OR) | 只要有一边为真,结果就为真。短路特性:如果左边为真,右边不再执行。 | |
| `!` | 逻辑非 (NOT) | 取反,真变假,假变真。 | ||
bool hasLogin = true; bool hasPermission = false; if (hasLogin && !hasPermission) { Console.WriteLine("已登录但无权限"); }
3. 比较/关系运算符 (Relational Operators)
用于比较两个值,返回 `true` 或 `false`。
| 运算符 | 描述 |
|---|---|
| `==` | 等于 |
| `!=` | 不等于 |
| `>` | 大于 |
| `<` | 小于 |
| `>=` | 大于等于 |
| `⇐` | 小于等于 |
4. 类型检查与转换运算符 (Type Testing & Casting)
在处理多态、接口或不确定类型的对象时非常重要。
4.1 is 运算符
用于检查对象是否兼容于指定类型。C# 7.0+ 支持模式匹配。
object obj = "Hello World"; // 传统用法 if (obj is string) { Console.WriteLine("是字符串"); } // 模式匹配用法 (推荐) if (obj is string str) { // 如果转换成功,str 变量直接可用 Console.WriteLine($"字符串长度: {str.Length}"); }
4.2 as 运算符
用于显式引用转换。如果转换失败,返回 `null` 而不是抛出异常。
object obj = "Hello"; string s = obj as string; // 转换成功 System.IO.Stream stream = obj as System.IO.Stream; // 转换失败,stream 为 null if (stream != null) { /*...*/ }
4.3 typeof 运算符
用于获取类型的 `System.Type` 对象(通常用于反射)。
Type t = typeof(string); Console.WriteLine(t.FullName); // System.String
5. 位运算符 (Bitwise Operators)
用于直接操作整数的二进制位。
| 运算符 | 描述 | 示例 (假设 A=60, B=13) | ||
|---|---|---|---|---|
| `&` | 按位与 | `A & B` (对应位都为1则为1) | ||
| ` | ` | 按位或 | `A | B` (对应位有一个为1则为1) |
| ` | ` | 按位异或 | `A | B` (对应位不同则为1) |
| `~` | 按位取反 | `~A` (0变1,1变0) | ||
| `«` | 左移 | `A « 2` (左移2位,相当于乘以4) | ||
| `»` | 右移 | `A » 2` (右移2位,相当于除以4) |
6. Lambda 运算符 (=>)
读作 “goes to”。用于定义 Lambda 表达式(匿名函数)。
// 参数 => 表达式 Func<int, int> square = x => x * x; Console.WriteLine(square(5)); // 25 // 在 LINQ 中广泛使用 var list = new List<int> { 1, 2, 3 }; var evens = list.Where(n => n % 2 == 0);
7. 索引与范围运算符 (Index & Range)
(C# 8.0+) 用于简化数组或集合的切片操作。
| 运算符 | 名称 | 描述 | ||
|---|---|---|---|---|
| ` | ` | 索引运算符 | 从末尾开始计数。` | 1` 是最后一个元素。 |
| `..` | 范围运算符 | 定义一个范围。`start..end` (包含 start,不包含 end)。 |
var words = new string[] { "The", "quick", "brown", "fox" }; // 获取最后一个元素 string last = words[^1]; // "fox" // 获取中间两个元素 (索引1到索引3,不含3) string[] middle = words[1..3]; // ["quick", "brown"] // 获取最后两个 string[] lastTwo = words[^2..]; // ["brown", "fox"]
8. ? 与 ?? (Null 处理与条件逻辑)
在 C# 中,`?` 和 `??` 运算符主要用于处理 null 值(空值) 以及 条件逻辑。它们不仅能简化代码,还能显著提高代码的可读性和安全性(防止空引用异常)。
8.1. ? 运算符 (单问号)
`?` 符号在 C# 中有三种截然不同的用法,取决于上下文。
8.1.1 可空类型修饰符 (Nullable Type Modifier)
用于定义一个值类型(如 `int`, `double`, `bool`, `DateTime` 等)可以存储 `null`。
- 原理:`int?` 实际上是 `System.Nullable<int>` 的语法糖。
- 场景:数据库中的数字字段可能为空,或者需要表示“未设置”的状态。
int a = 10; // 正常 int,不能赋值 null int? b = null; // 可空 int,可以赋值 null if (b.HasValue) { Console.WriteLine(b.Value); }
8.1.2 三元条件运算符 (Ternary Conditional Operator)
这是 `if-else` 语句的简写形式,用于根据布尔表达式返回两个值中的一个。
- 语法:`condition ? true_value : false_value`
- 含义:如果条件为真,返回冒号左边的值;否则返回冒号右边的值。
int x = 10; string result = (x > 5) ? "大于5" : "小于等于5";
8.1.3 Null 条件运算符 (Null-conditional Operator)
(C# 6.0+) 也称为“安全导航运算符”。用于在访问成员(属性、方法)或索引器之前检查对象是否为 `null`。
- 语法:`obj?.Property` 或 `arr?[index]`
- 含义:如果对象不为 `null`,则访问成员;如果对象为 `null`,则整个表达式直接返回 `null`,而不会抛出 `NullReferenceException`。
string text = null; // length 将会是 null (int?),而不是抛出异常 int? length = text?.Length; // 链式调用 Person person = null; string city = person?.Address?.City; // 如果 person 或 Address 为 null,city 为 null
8.2. ?? 运算符 (双问号)
`??` 系列运算符主要用于处理 null 时的默认值逻辑。
2.1 Null 合并运算符 (Null-coalescing Operator)
用于判断左侧的操作数是否为 `null`。
- 语法:`left ?? right`
- 含义:如果 `left` 不为 `null`,则返回 `left`;如果 `left` 为 `null`,则返回 `right`。
string input = null; // 如果 input 是 null,则 name 变成 "DefaultName" string name = input ?? "DefaultName";
2.2 Null 合并赋值运算符 (Null-coalescing Assignment Operator)
(C# 8.0+) 这是 `??` 和 `=` 的组合。
- 语法:`variable ??= value`
- 含义:只有当左侧变量 `variable` 为 `null` 时,才将右侧的 `value` 赋值给它。如果左侧不为 null,则保持原值不变。
List<int> numbers = null; // 因为 numbers 是 null,所以会初始化新列表 numbers ??= new List<int>(); // 此时 numbers 已不是 null,这行代码不会执行任何操作 numbers ??= new List<int>();
3. 综合代码示例
以下示例展示了如何在一个场景中混合使用上述运算符。
using System; using System.Collections.Generic; public class Program { public static void Main() { // 1. 可空类型修饰符 (?) int? nullableInt = null; // 2. Null 合并运算符 (??) // 如果 nullableInt 是 null,则使用默认值 0 int finalValue = nullableInt ?? 0; Console.WriteLine($"1. Null合并结果: {finalValue}"); // 输出: 0 // 3. 三元运算符 (?:) string status = (finalValue > 5) ? "High" : "Low"; Console.WriteLine($"2. 三元运算结果: {status}"); // 输出: Low // 4. Null 条件运算符 (?.) Person person = null; // 如果 person 为 null,name 直接为 null,不会报错 string name = person?.Name; Console.WriteLine($"3. Null条件访问: '{name}'"); // 输出: '' (空) // 组合使用:安全访问 + 默认值 // 如果 person 为 null 或者 Name 为 null,则显示 "Unknown" string displayName = person?.Name ?? "Unknown"; Console.WriteLine($"4. 组合使用结果: {displayName}"); // 输出: Unknown // 5. Null 合并赋值运算符 (??=) List<string> tags = null; // 因为 tags 是 null,所以进行赋值 tags ??= new List<string>(); tags.Add("C#"); Console.WriteLine($"5. 列表元素数量: {tags.Count}"); // 输出: 1 } } public class Person { public string Name { get; set; } }
4. 总结表
| 运算符 | 名称 | 语法示例 | 解释 |
|---|---|---|---|
| `?` | 可空类型修饰符 | `int? x` | 允许值类型为 null。 |
| `?:` | 三元运算符 | `a ? b : c` | 如果 a 为真选 b,否则选 c。 |
| `?.` | Null 条件运算符 | `obj?.Prop` | 如果 obj 非空则访问 Prop,否则返回 null。 |
| `??` | Null 合并运算符 | `a ?? b` | 如果 a 非空返回 a,否则返回 b (默认值)。 |
| `??=` | Null 合并赋值 | `a ??= b` | 仅当 a 为 null 时,将 b 赋值给 a。 |
8. 综合总结表
| 类别 | 常用运算符 | 关键点 | ||||
|---|---|---|---|---|---|---|
| 算术 | `+`, `-`, `*`, `/`, `%`, `++`, `–` | 注意整数除法会丢失小数。 | ||||
| 逻辑 | `&&`, ` | `, `!` | `&&` 和 ` | ` 具有短路特性。 | ||
| 比较 | `==`, `!=`, `>`, `<`, `>=`, `⇐` | 结果总是 bool 类型。 | ||||
| 位运算 | `&`, ` | `, ` | `, `~`, `«`, `»` | 用于底层二进制操作。 | ||
| 赋值 | `=`, `+=`, `-=`, `*=`, `/=` | `x += 5` 等同于 `x = x + 5`。 | ||||
| 类型 | `is`, `as`, `typeof`, `(T)x` | `as` 转换失败返回 null,`(T)` 强制转换失败抛异常。 | ||||
| Lambda | `⇒` | 连接参数和方法体,用于 LINQ 和委托。 | ||||
| 索引/范围 | ` | `, `..` | C# 8.0 新特性,用于数组切片。 | |||
| Null处理 | `?`, `??`, `?.`, `??=` | 参见之前的 Null 运算符文档。 | ||||