-
条件语句:if-else与switch
3.1 条件语句:if-else与switch
在程序运行时,我们经常需要根据不同的条件执行不同的逻辑(例如:根据用户分数判断等级、根据角色权限展示不同功能菜单)。条件语句是实现这一需求的核心工具,C#提供了两种主要的条件语句:if-else(灵活的范围判断)和switch(高效的离散值匹配)。本节将通过实例详解两者的语法、使用场景及高级特性,并延伸讲解代码优化与常见问题。
3.1.1 if-else语句:灵活的范围判断
if-else语句通过判断条件表达式的true/false来执行不同的代码块,适用于范vb.net教程C#教程python教程SQL教程access 2010教程围判断(如“分数>90”“年龄<18”)或复杂条件组合(如“成绩>80且出勤>90”)。
基础语法结构
csharp
// 单分支:条件为true则执行
if (条件表达式)
{
// 条件成立时执行的代码块
}
// 双分支:条件为true执行分支1,false执行分支2
if (条件表达式)
{
// 分支1(条件成立)
}
else
{
// 分支2(条件不成立)
}
// 多分支:依次判断条件,满足则执行对应分支,均不满足则执行else
if (条件1)
{
// 分支1(条件1成立)
}
else if (条件2)
{
// 分支2(条件1不成立,条件2成立)
}
// ... 更多else if
else
{
// 所有条件均不成立时执行
}
实例3-1:if-else双分支判断成绩是否及格
需求:用户输入分数(0-100),判断是否及格(>=60为及格,否则不及格),并输出结果。
csharp
using System;
class IfElseDemo1
{
static void Main()
{
// 1. 提示用户输入分数
Console.Write("请输入您的分数(0-100):");
// 2. 读取用户输入并转换为int类型
string input = Console.ReadLine(); // 读取输入的字符串(如"85")
int score = int.Parse(input); // 将字符串转换为整数(如"85"→85)
// 3. 用if-else判断是否及格
if (score >= 60) // 条件表达式:分数>=60?
{
// 条件成立(true):输出“及格”
Console.WriteLine("成绩及格!");
}
else
{
// 条件不成立(false):输出“不及格”
Console.WriteLine("成绩不及格!");
}
}
}
逐行代码讲解:
using System;:引入System命名空间,包含Console类(用于输入输出)。
class IfElseDemo1:定义类,C#程序代码必须放在类中。
static void Main():程序入口方法,程序从这里开始执行。
Console.Write("请输入您的分数(0-100):");:Write方法输出提示文本,不换行,等待用户输入。
string input = Console.ReadLine();:ReadLine()读取用户输入的一行文本(如用户输入“85”,input值为"85")。
int score = int.Parse(input);:int.Parse将字符串转换为int类型(如"85"→85)。若输入非数字(如“abc”),会抛出FormatException(后续异常处理章节讲解)。
if (score >= 60):条件表达式score >= 60,结果为bool类型(true或false)。若用户输入85,85 >= 60为true,执行if代码块;若输入50,条件为false,执行else代码块。
Console.WriteLine("成绩及格!");:条件成立时输出“及格”,否则输出else块中的“不及格”。
实例3-2:if-else if-else多分支判断成绩等级
需求:将分数分为更细的等级(90-100优秀,80-89良好,70-79中等,60-69及格,<60不及格),根据输入分数输出对应等级。
csharp
using System;
class IfElseDemo2
{
static void Main()
{
Console.Write("请输入分数(0-100):");
int score = int.Parse(Console.ReadLine()); // 合并读取和转换(省略中间变量input)
// 多分支判断:从高到低检查条件(注意顺序!)
if (score >= 90 && score <= 100) // 条件1:90-100(含边界)
{
Console.WriteLine("优秀");
}
else if (score >= 80) // 隐含条件:score <90(因条件1不成立),故80-89
{
Console.WriteLine("良好");
}
else if (score >= 70) // 隐含条件:score <80,故70-79
{
Console.WriteLine("中等");
}
else if (score >= 60) // 隐含条件:score <70,故60-69
{
Console.WriteLine("及格");
}
else if (score >= 0) // 条件:0-59
{
Console.WriteLine("不及格");
}
else // 所有条件不成立:分数<0(无效输入)
{
Console.WriteLine("输入错误!分数不能为负数。");
}
}
}
关键逻辑解析:
条件顺序:多分支if-else if-else中,条件判断是自上而下依次执行的,一旦某个条件成立,后续条件不再判断。因此,范围判断需按“从大到小”或“从小到大”排列,避免逻辑错误。例如,若将score >= 60放在score >= 90前面,则90分以上的成绩会先匹配到“及格”,而非“优秀”。
隐含条件:else if (score >= 80)的完整条件是score <90 && score >=80(因前一个条件score >=90不成立),代码中可省略score <90,简化逻辑。
边界处理:最后一个else处理无效输入(如-10分),确保程序对异常情况有响应,而非直接崩溃。
3.1.2 switch语句:高效的离散值匹配
switch语句用于根据单个变量的离散值(如整数、字符串、枚举)执行不同逻辑,代码结构比多分支if-else更清晰(尤其当条件值较多时)。C# 8.0后,switch支持模式匹配,功能更强大。
传统switch语法(C# 8.0前)
csharp
switch (表达式) // 表达式类型:整数、字符串、枚举等(需支持相等比较)
{
case 值1: // 当表达式等于值1时执行
代码块1;
break; // 跳出switch,避免“贯穿”
case 值2:
代码块2;
break;
// ... 更多case
default: // 所有case不匹配时执行(可选)
默认代码块;
break; // default后可省略break(但建议保留,保持一致)
}
实例3-3:传统switch判断星期几
需求:输入数字1-7,输出对应中文星期(1→周一,2→周二,...,7→周日),无效数字输出“输入错误”。
csharp
using System;
class SwitchDemo1
{
static void Main()
{
Console.Write("请输入星期数字(1-7):");
int day = int.Parse(Console.ReadLine());
switch (day) // 表达式为变量day
{
case 1: // day == 1
Console.WriteLine("星期一");
break; // 执行后跳出switch
case 2:
Console.WriteLine("星期二");
break;
case 3:
Console.WriteLine("星期三");
break;
case 4:
Console.WriteLine("星期四");
break;
case 5:
Console.WriteLine("星期五");
break;
case 6:
Console.WriteLine("星期六");
break;
case 7:
Console.WriteLine("星期日");
break;
default: // day不是1-7时执行
Console.WriteLine("输入错误!请输入1-7的数字。");
break;
}
}
}
关键语法解析:
case值唯一性:每个case后的值必须唯一(如不能有两个case 1),且必须是编译时常量(如整数、字符串字面量,不能是变量)。
break的作用:若省略break,会发生“贯穿(fall-through)”——执行当前case后,继续执行下一个case(不判断条件),可能导致逻辑错误。C#中,除“空case”(仅用于合并case)外,不允许隐式贯穿,必须显式用break、return或goto case跳出。
default的位置:default可放在任意位置(不一定在最后),但建议放在末尾,逻辑更清晰。若所有case均不匹配且无default,switch不执行任何代码。
现代switch表达式(C# 8.0+)
C# 8.0引入switch表达式,语法更简洁,支持模式匹配,可直接返回值,替代传统的多分支if-else或复杂switch。
语法:
csharp
结果变量 = 表达式 switch
{
模式1 => 结果1,
模式2 => 结果2,
// ... 更多模式
_ => 默认结果 // _(弃元)匹配所有未覆盖的情况,类似default
};
实例3-4:switch表达式判断季节
需求:输入月份(1-12),用switch表达式判断季节(3-5春,6-8夏,9-11秋,12-2冬)。
csharp
using System;
class SwitchExpressionDemo
{
static void Main()
{
Console.Write("请输入月份(1-12):");
int month = int.Parse(Console.ReadLine());
// switch表达式:根据month返回季节字符串
string season = month switch
{
3 or 4 or 5 => "春季", // 合并case:3、4、5月→春季(or关键字合并模式)
6 or 7 or 8 => "夏季",
9 or 10 or 11 => "秋季",
12 or 1 or 2 => "冬季",
_ => "无效月份" // 弃元_匹配所有其他值(如0、13)
};
Console.WriteLine($"该月份属于:{season}");
}
}
关键新特性解析:
简洁语法:用=>替代case和break,直接返回结果,代码行数减少50%以上。
合并case:用or关键字合并多个值(如3 or 4 or 5),替代传统switch的“空case+goto”写法(更优雅)。
弃元(_):_表示“匹配所有未覆盖的情况”,必须放在最后,确保覆盖所有可能值,避免编译错误。
模式匹配:除常量模式(如1、2)外,还支持类型模式(x is int i)、属性模式(p => p.Age > 18)等,例如:
csharp
object obj = "hello";
string type = obj switch
{
int i => $"整数:{i}",
string s => $"字符串:{s}",
_ => "未知类型"
}; // type结果为“字符串:hello”(类型模式匹配)
3.1.3 知识点扩展:if-else与switch的深度对比
- 适用场景
| 场景 | 推荐语句 | 理由 |
|---|---|---|
| 范围判断(如score >=90) | if-else switch(传统) | 不支持范围,需用模式匹配(C# 8.0+),但if-else更直观。 |
| 离散值匹配(如星期、月份) | switch | 代码结构清晰,执行效率更高(编译器可优化为跳转表)。 |
| 复杂条件组合(如a>10 && b<20) | if-else | switch表达式支持模式匹配,但复杂组合仍需if-else。 |
| 简单值返回(如根据条件返回字符串) | switch表达式 | 语法最简洁(一行代码搞定),替代if (x) return a; else return b;。 |
-
性能对比
if-else:多分支时,需依次判断条件(最坏情况判断所有条件),效率较低(尤其条件值无序时)。
switch:编译器会将离散值条件优化为跳转表(类似数组索引),直接定位到匹配的case,效率更高(O(1)时间复杂度)。但对于字符串类型,C#会先计算哈希值,再匹配哈希表,效率仍优于多分支if-else。 -
switch的高级模式匹配(C# 8.0+)
类型模式:判断对象类型并转换,例如:
csharp
void PrintValue(object obj)
{
string result = obj switch
{
int i => $"整数:{i * 2}", // 若obj是int,转换为i并计算
string s => $"字符串长度:{s.Length}", // 若obj是string,获取长度
_ => "未知类型"
};
Console.WriteLine(result);
}
PrintValue(5); // 输出“整数:10”
PrintValue("hello"); // 输出“字符串长度:5”
属性模式:判断对象的属性值,例如:
csharp
class Person { public string Name { get; set; } public int Age { get; set; } }
string GetStatus(Person p) => p switch
{
{ Age < 18 } => "未成年",
{ Age >= 18, Name: "管理员" } => "成年管理员", // 多属性匹配
_ => "普通成年"
};
3.1.4 基础知识延伸
-
条件运算符(?:):简化if-else
条件运算符(三元运算符)是if-else的简写形式,适合简单的“二选一”判断,语法:
csharp
条件 ? 表达式1 : 表达式2; // 条件为true,返回表达式1;否则返回表达式2
实例:
csharp
int score = 85;
string result = score >= 60 ? "及格" : "不及格"; // 等价于if-else判断
Console.WriteLine(result); // 输出“及格”
注意:条件运算符可嵌套,但嵌套过深会降低可读性,建议嵌套不超过2层。
2. 常见错误与规避
浮点值比较:避免用==直接比较float/double(因精度误差,如0.1 + 0.2实际为0.30000000000000004,不等于0.3)。应判断两数之差的绝对值是否小于极小值(如Math.Abs(a - b) < 1e-6)。
忘记break导致贯穿:传统switch中,case后必须加break,否则编译报错(C#不允许隐式贯穿)。
switch表达式未覆盖所有情况:若表达式可能的值未被完全覆盖且无_(弃元),编译报错。例如,枚举类型的switch表达式需覆盖所有枚举值,或用_处理默认情况。
3. 代码风格建议
缩进:条件语句的代码块必须缩进(通常4个空格),清晰区分嵌套层次。
大括号:即使代码块只有一行,也建议用大括号{}包裹(避免后续添加代码时逻辑错误)。例如:
csharp
// 不推荐(易出错)
if (score >= 60)
Console.WriteLine("及格");
Console.WriteLine("继续努力"); // 该行不属于if块,无论条件如何都会执行
// 推荐
if (score >= 60)
{
Console.WriteLine("及格");
Console.WriteLine("继续努力");
}
总结
if-else:灵活处理范围判断和复杂条件,语法直观,适合条件较少或范围场景。
switch:传统语法适合离散值匹配,现代switch表达式(C# 8.0+)支持模式匹配,语法简洁,适合返回值场景。
选择原则:范围用if-else,离散值用switch,简单返回用switch表达式。
扩展技能:掌握模式匹配(C# 8.0+)可大幅提升switch的灵活性,条件运算符简化简单判断,代码风格和常见错误规避提升程序健壮性。
条件语句是控制程序逻辑的基础,后续循环、方法、面向对象编程中均会频繁使用,需熟练掌握其语法和最佳实践。
本站原创,转载请注明出处:https://www.xin3721.com/ArticlecSharp/c49343.html










