淡若轻风

博客园 首页 新随笔 联系 订阅 管理

背景描述:

当在代码中需要实现“二选一”需求时,如何实现,代码会更简洁。

 在 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 方法

// 推荐
if (isSuccess)
{
    LogSuccess();
}
else
{
    LogFailure();
}

不能写成:

isSuccess ? LogSuccess() : LogFailure();  // 编译错误,条件表达式不能单独作语句

即使方法有返回值,也不建议为了用 ?: 而写:

_ = isSuccess ? LogSuccess() : LogFailure();  // 能编译,但可读性差

 

3.3 多分支 else if

if (score >= 90)
{
    level = "A";
}
else if (score >= 80)
{
    level = "B";
}
else if (score >= 70)
{
    level = "C";
}
else
{
    level = "D";
}

 

用嵌套三元会变成:

string level = score >= 90 ? "A"
             : score >= 80 ? "B"
             : score >= 70 ? "C"
             : "D";

 

这种写法虽然能编译,但可读性明显下降,不推荐。多分支更适合 switch 表达式:

string level = score switch
{
    >= 90 => "A",
    >= 80 => "B",
    >= 70 => "C",
    _     => "D"
};

 


4. 嵌套三元表达式:尽量别超过一层

不推荐:

string result = a ? b ? "X" : "Y" : c ? "Z" : "W";

 

这种代码需要人脑解析括号,容易出错。应改为 if...else 或 switch。

如果确实要用,至少加括号并格式化:

string result = a
    ? (b ? "X" : "Y")
    : (c ? "Z" : "W");

 

但仍然不如 if...else 清晰。


5. 返回值和赋值场景的对比

推荐用 ?:

public decimal GetPrice(User user)
{
    return user.IsVip ? 0.8m : 1.0m;
}

 

推荐用 if...else

public decimal GetPrice(User user)
{
    if (user == null)
    {
        throw new ArgumentNullException(nameof(user));
    }

    if (user.IsVip)
    {
        return 0.8m;
    }

    return 1.0m;
}

判断标准:分支里是否有校验、抛异常、日志、多步计算。有,就用 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。

posted on 2026-09-21 11:27  淡若轻风  阅读(6)  评论(0)    收藏  举报