背景描述:
当在代码中需要实现“二选一”需求时,如何实现,代码会更简洁。
在 C# 里,if...else 和条件表达式 ?: 都能做“二选一”,但它们的定位不同:
-
if...else是语句,用来控制流程,分支里可以执行任意代码。 -
?:是表达式,必须产生一个值,适合在两个值之间做选择。
选择的核心标准只有一条:可读性优先。一眼能看懂就用 ?:,稍微复杂就用 if...else。
1. 本质区别
| 对比项 | if...else | 条件表达式 ?: |
|---|---|---|
| 类型 | 语句 | 表达式 |
| 是否有返回值 | 没有,只控制流程 | 必须有返回值 |
| 分支内容 | 可以多行、多条语句、副作用 | 只能是表达式,通常是简单值或方法调用 |
| 多分支 | 支持 else if |
嵌套可读性差 |
| 适用场景 | 复杂逻辑、流程控制 | 简单赋值、返回、参数传递 |
| 性能 | 基本相同 | 基本相同 |
2. 什么时候用条件表达式 ?:
适合:两个分支都很简单,而且只是为了得到一个值。
// 简单赋值 string status = isOnline ? "在线" : "离线"; // 简单返回 return score >= 60 ? "及格" : "不及格"; // 作为参数 Console.WriteLine(isAdmin ? "管理员" : "普通用户"); // 处理 null,但更推荐 ?? 或 ?. string name = input != null ? input : "默认名称"; string name2 = input ?? "默认名称";
条件表达式还能用在表达式上下文中,比如 LINQ、字符串插值、Lambda:
var names = users.Select(u => u.IsActive ? u.Name : "已禁用");
3. 什么时候必须用 if...else
3.1 分支里要执行多条语句
if (isSuccess) { SaveResult(); Log("成功"); NotifyUser(); } else { Retry(); Log("失败"); }
条件表达式做不到这种多语句分支。
3.2 分支有副作用,尤其是 void 方法
3.3 多分支 else if
用嵌套三元会变成:
这种写法虽然能编译,但可读性明显下降,不推荐。多分支更适合 switch 表达式:
4. 嵌套三元表达式:尽量别超过一层
不推荐:
这种代码需要人脑解析括号,容易出错。应改为 if...else 或 switch。
如果确实要用,至少加括号并格式化:
但仍然不如 if...else 清晰。
5. 返回值和赋值场景的对比
推荐用 ?:
推荐用 if...else
6. 性能问题
if...else 和 ?: 在性能上没有本质区别。编译器通常会生成类似的 IL,JIT 也会做优化。不要为了性能选 ?:,只为了可读性。
7. 实用选择清单
| 场景 | 推荐 |
|---|---|
| 简单二选一赋值 | ?: |
| 简单二选一返回 | ?: |
| 作为方法参数 | ?: |
| LINQ / Lambda 中 | ?: |
| 分支执行多条语句 | if...else |
分支调用 void 方法 |
if...else |
有 else if 多分支 |
if...else |
| 嵌套超过一层 | 改用 if...else 或 switch |
| 多模式匹配 | switch 表达式 |
| null 合并 | ?? |
| null 条件访问 | ?. |
8. 一句话总结
?: 用来“选一个值”,if...else 用来“控制一段流程”。
-
如果两个分支都只是简单表达式,而且结果立刻被使用,用
?:。 -
如果分支里要做多件事、有副作用、有复杂条件或多层分支,用
if...else。 -
读起来费劲的代码,无论能不能用
?:,都应该改成if...else或switch。
浙公网安备 33010602011771号