07-条件判断
条件判断是编程中非常重要的逻辑控制手段,用于根据不同的条件执行不同的代码。C# 提供了多种条件判断方式。
一、if-else 语句
基本语法
csharp
if (条件)
{
// 条件为 true 时执行
}
else if (其他条件)
{
// 其他条件为 true 时执行
}
else
{
// 所有条件都不满足时执行
}示例
csharp
int score = 85;
if (score >= 90)
Console.WriteLine("优秀");
else if (score >= 80)
Console.WriteLine("良好");
else if (score >= 60)
Console.WriteLine("及格");
else
Console.WriteLine("不及格");注意: 当代码块只有一行时,可以省略花括号,但不推荐(容易出错)。
嵌套 if
csharp
int number = 15;
if (number > 0)
{
if (number % 2 == 0)
Console.WriteLine("正偶数");
else
Console.WriteLine("正奇数");
}避免嵌套过深(超过 3 层),考虑使用 switch 或提前 return。
二、switch 语句
传统 switch
csharp
int day = 3;
string dayName;
switch (day)
{
case 1:
dayName = "星期一";
break;
case 2:
dayName = "星期二";
break;
case 3:
dayName = "星期三";
break;
case 4:
dayName = "星期四";
break;
case 5:
dayName = "星期五";
break;
case 6:
case 7:
dayName = "周末";
break;
default:
dayName = "无效的星期";
break;
}
Console.WriteLine(dayName); // 星期三switch 的注意事项
- 每个
case必须以break、return、throw或goto结束 - C# 不支持 case 穿透(fall-through),除非 case 为空(多个 case 共享代码)
default是可选的
三、switch 表达式(C# 8.0+)
switch 表达式是 switch 语句的更简洁的表达式版本。
csharp
// 传统 switch 语句
string GetGrade(int score)
{
switch (score)
{
case >= 90: return "优秀";
case >= 80: return "良好";
case >= 60: return "及格";
default: return "不及格";
}
}
// switch 表达式(简洁!)
string GetGrade2(int score) => score switch
{
>= 90 => "优秀",
>= 80 => "良好",
>= 60 => "及格",
_ => "不及格" // _ 相当于 default
};
// 多条件匹配
string Describe(object obj) => obj switch
{
int i when i > 0 => $"正数:{i}",
int i when i < 0 => $"负数:{i}",
int i => "零",
string s => $"字符串:{s}",
null => "null",
_ => $"其他类型:{obj.GetType().Name}"
};switch 表达式 vs switch 语句
| 对比项 | switch 语句 | switch 表达式 |
|---|---|---|
| 语法 | switch + case | 表达式 switch { } |
| 返回值 | 需要手动赋值或 return | 直接返回结果 |
| case 关键字 | 需要 | 不需要 |
| default | default: | _ => |
| 简洁性 | 冗长 | 简洁 |
| 模式匹配 | 支持 | 支持丰富模式 |
四、模式匹配(Pattern Matching)
C# 7.0+ 引入了强大的模式匹配功能。
1. 类型模式
csharp
object obj = "Hello";
// 传统方式
if (obj is string)
{
string s = (string)obj;
Console.WriteLine(s.Length);
}
// 模式匹配:检查 + 转换一步到位
if (obj is string s)
{
Console.WriteLine(s.Length); // ✅ 直接使用 s
}
// 取反模式(C# 9.0+)
if (obj is not int)
{
Console.WriteLine("不是整数");
}2. 属性模式
csharp
class Point
{
public int X { get; set; }
public int Y { get; set; }
}
string DescribePoint(Point p) => p switch
{
{ X: 0, Y: 0 } => "原点",
{ X: 0 } => "Y 轴上",
{ Y: 0 } => "X 轴上",
_ => $"({p.X}, {p.Y})"
};3. 元组模式
csharp
// 石头剪刀布
string RockPaperScissors(string player1, string player2) =>
(player1, player2) switch
{
("石头", "剪刀") => "玩家1 获胜",
("剪刀", "布") => "玩家1 获胜",
("布", "石头") => "玩家1 获胜",
_ when player1 == player2 => "平局",
_ => "玩家2 获胜"
};
Console.WriteLine(RockPaperScissors("石头", "剪刀")); // 玩家1 获胜五、三元运算符
简洁的条件判断表达式,返回一个值。
csharp
// 语法:条件 ? 为真时 : 为假时
int number = 10;
string result = number > 0 ? "正数" : "非正数";
Console.WriteLine(result); // 正数
// 嵌套三元(可读性差,不推荐)
string status = number > 0 ? "正数" : number < 0 ? "负数" : "零";
// 推荐:用 if-else 代替嵌套三元
string GetStatus(int n)
{
if (n > 0) return "正数";
if (n < 0) return "负数";
return "零";
}六、空值处理运算符
1. 空合并运算符 ??
csharp
string? name = null;
string display = name ?? "未知用户"; // name 为 null 时使用默认值
Console.WriteLine(display); // 未知用户
// 链式使用
string? a = null, b = null, c = "Hello";
string result = a ?? b ?? c ?? "全部为 null";
Console.WriteLine(result); // Hello
// ??= 赋值(C# 8.0+)
string? text = null;
text ??= "默认值"; // text 为 null 时赋值
Console.WriteLine(text); // 默认值2. 空条件运算符 ?.
csharp
class Person
{
public string? Name { get; set; }
public Address? Address { get; set; }
}
class Address
{
public string? City { get; set; }
}
Person? person = null;
// 安全访问成员——任一环节为 null 则结果为 null
string? city = person?.Address?.City ?? "未知城市";
Console.WriteLine(city); // 未知城市
// 安全调用方法
Action? action = null;
action?.Invoke(); // action 为 null 时不执行,不抛异常
// 安全访问数组元素
int[]? numbers = null;
int? first = numbers?[0]; // null,而不是异常3. 空值运算符对比
| 运算符 | 名称 | 用途 | 示例 |
|---|---|---|---|
?? | 空合并 | 左侧为 null 时返回右侧 | name ?? "默认" |
??= | 空合并赋值 | 左侧为 null 时赋值 | name ??= "默认" |
?. | 空条件 | 安全访问成员 | person?.Name |
?[i] | 空条件索引 | 安全访问索引 | arr?[0] |
七、条件判断方式选择指南
| 场景 | 推荐方式 | 示例 |
|---|---|---|
| 2-3 个分支,较简单 | if-else | 成绩等级判断 |
| 多个固定值匹配 | switch 或 switch 表达式 | 星期、状态码 |
| 类型检查和转换 | 模式匹配 is | obj is string s |
| 简单二选一返回值 | 三元运算符 | a > b ? a : b |
| null 默认值 | ?? 运算符 | name ?? "默认" |
| 安全访问成员 | ?. 运算符 | person?.Name |
八、综合案例:订单折扣系统
csharp
public class Order
{
public decimal Amount { get; set; }
public string CustomerType { get; set; } // "普通", "VIP", "企业"
public int YearsAsCustomer { get; set; }
public bool IsHoliday { get; set; }
}
// 使用多种条件判断方式
static decimal CalculateDiscount(Order order)
{
// 空值检查
if (order == null)
throw new ArgumentNullException(nameof(order));
// 基础折扣——使用 switch 表达式
decimal baseDiscount = order.CustomerType switch
{
"VIP" => 0.15m,
"企业" => 0.10m,
"普通" => 0.05m,
_ => 0m
};
// 老客户额外折扣——使用三元
decimal loyaltyDiscount = order.YearsAsCustomer > 5 ? 0.05m : 0m;
// 节假日折扣——使用 if
decimal holidayDiscount = 0;
if (order.IsHoliday && order.Amount > 100)
{
holidayDiscount = 0.03m;
}
// 总折扣(不超过 30%)——使用 ?? 确保不会有 null
decimal totalDiscount = Math.Min(baseDiscount + loyaltyDiscount + holidayDiscount, 0.30m);
return order.Amount * totalDiscount;
}
// 使用
var order = new Order
{
Amount = 1000,
CustomerType = "VIP",
YearsAsCustomer = 6,
IsHoliday = true
};
decimal discount = CalculateDiscount(order);
Console.WriteLine($"折扣金额:{discount:C}"); // 折扣金额:230.00核心知识点总结
条件判断方式对比
| 方式 | 适用场景 | 返回值 | 可读性 |
|---|---|---|---|
| if-else | 任何条件判断 | 无 | 好 |
| switch 语句 | 多固定值匹配 | 无 | 一般 |
| switch 表达式 | 多条件返回结果 | 有返回值 | 好 |
| 三元运算符 | 简单二选一 | 有返回值 | 简洁 |
?? / ?. | 空值处理 | 有返回值 | 简洁 |
注意事项
- if-else 条件必须是 bool 类型——C# 不允许
if (1)这样的写法 - switch 的每个 case 需要 break——不像 C++ 可以穿透
- 三元运算符不要嵌套——超过一层应使用 if-else
- ?. 和 ?? 配合使用——实现安全的空值处理链
- switch 表达式是表达式不是语句——必须有返回值,所有情况都要覆盖
- 模式匹配使代码更简洁——优先使用
is模式匹配替代is+ 强制转换 - 避免深层嵌套——超过 3 层应考虑重构


