C# 条件与循环

程序的"灵魂"是做判断 + 重复干活——这正是控制流做的事。这一篇我们把 C# 的条件(if、switch)和循环(for、foreach、while)全部过完,顺便认识一下现代 C# 的switch 表达式,它是写干净代码的关键工具。

一、if-else 条件

最基础的条件判断。语法和 C/Java 一样:

int score = 78;

if (score >= 90)
{
    Console.WriteLine("优秀");
}
else if (score >= 60)
{
    Console.WriteLine("及格");
}
else
{
    Console.WriteLine("不及格");
}

// 单行可省略花括号(不推荐,易出错)
if (score > 100)
    Console.WriteLine("无效分数");

// 条件表达式可以是复杂逻辑
bool hasHomework = true;
bool finished = false;
if (!finished && hasHomework && score > 60)
{
    Console.WriteLine("继续做作业");
}

几个建议:

二、switch 语句

多分支判断,比一长串 if-else 清晰:

// 传统 switch 语句
int day = 3;
switch (day)
{
    case 1:
        Console.WriteLine("周一");
        break;        // 必须有 break,不像 C/C++ 可隐式贯穿
    case 2:
        Console.WriteLine("周二");
        break;
    case 6:
    case 7:
        Console.WriteLine("周末");
        break;
    default:
        Console.WriteLine("工作日");
        break;
}

// switch 必须有 break/return/goto,不能贯穿(除非 case 之间无语句)
// 这避免了 C/C++ 忘写 break 的经典 bug

C# 的 switch 强制每个 case 用 break/return(不能贯穿),避免了 C/C++ 忘写 break 的经典 bug。空 case 可以连写(case 6: case 7: 表示共享代码)。

三、switch 表达式(C# 8+,强推!)

这是现代 C# 的大杀器——把 switch 变成"返回值的表达式",配合模式匹配极其优雅:

// C# 8+ switch 表达式(强推!)
int score = 78;
string grade = score switch
{
    >= 90 => "A",
    >= 80 => "B",
    >= 60 => "C",
    _ => "D"           // _ 是弃元,匹配其他所有情况
};
// "C"

// 枚举 switch
enum TrafficLight { Red, Yellow, Green }

TrafficLight light = TrafficLight.Yellow;
string action = light switch
{
    TrafficLight.Red => "停",
    TrafficLight.Yellow => "准备",
    TrafficLight.Green => "行",
    _ => throw new ArgumentException()
};

// 元组 switch
string classify(int x, int y) => (x, y) switch
{
    (0, 0) => "原点",
    (_, 0) => "x 轴",
    (0, _) => "y 轴",
    (_, _) => "其他"
};

对比传统 switch 语句,优势巨大:

实际开发中,90% 的多分支场景应该用 switch 表达式,传统 switch 语句留给"分支里要做很多事"的场景。

四、for 循环

知道循环次数时用 for:

// for 循环:知道次数时用
for (int i = 0; i < 5; i++)
{
    Console.WriteLine($"第 {i + 1} 次");
}
// 输出 第 1 次 ... 第 5 次

// 倒序
for (int i = 10; i > 0; i--)
    Console.WriteLine(i);

// 步长为 2
for (int i = 0; i < 20; i += 2)
    Console.WriteLine(i);   // 0 2 4 ... 18

// 嵌套循环(九九乘法表)
for (int i = 1; i <= 9; i++)
{
    for (int j = 1; j <= i; j++)
        Console.Write($"{j}×{i}={i * j}\t");
    Console.WriteLine();
}

for 的三段(初始化、条件、迭代)都是可选的,for (;;) 是无限循环(等价 while (true))。

五、foreach 循环(C# 推荐)

遍历集合优先用 foreach,比 for 简洁,不易错:

// foreach:遍历集合,最简洁
string[] fruits = { "苹果", "香蕉", "橙子" };
foreach (var f in fruits)
    Console.WriteLine(f);

// 遍历 List
var nums = new List<int> { 10, 20, 30 };
foreach (int n in nums)
    Console.WriteLine(n);

// 遍历字典
var dict = new Dictionary<string, int>
{
    ["apple"] = 5,
    ["banana"] = 3
};
foreach (var kv in dict)
    Console.WriteLine($"{kv.Key}: {kv.Value}");

// 遍历字符串(字符序列)
foreach (char c in "Hello")
    Console.Write(c + " ");   // H e l l o

foreach 适用于所有 IEnumerable 集合(数组、List、Dictionary、字符串等)。需要索引时再用 for。

六、while 与 do-while

不知道循环次数、根据条件决定时用 while:

// while:条件成立时执行
int n = 5;
while (n > 0)
{
    Console.WriteLine(n);
    n--;
}

// do-while:先执行一次再判断
int i = 0;
do
{
    Console.WriteLine(i);
    i++;
} while (i < 5);

// 经典:读用户输入直到合法
string input;
do
{
    Console.Write("请输入 yes 或 no:");
    input = Console.ReadLine();
} while (input != "yes" && input != "no");

区别:

七、break、continue、return

// break:跳出整个循环
for (int i = 0; i < 100; i++)
{
    if (i == 5)
        break;        // i=5 时整个循环结束
    Console.WriteLine(i);   // 0 1 2 3 4
}

// continue:跳过本次,继续下一次
for (int i = 0; i < 10; i++)
{
    if (i % 2 == 0)
        continue;     // 偶数跳过
    Console.WriteLine(i);   // 1 3 5 7 9
}

// 嵌套循环用 break 只能跳出内层
for (int i = 0; i < 3; i++)
{
    for (int j = 0; j < 3; j++)
    {
        if (j == 1) break;   // 只跳出内层
    }
}

// goto 跳出多层(罕见但有时清晰)
for (int i = 0; i < 3; i++)
{
    for (int j = 0; j < 3; j++)
    {
        if (i + j > 3)
            goto outer;     // 直接跳出所有
    }
}
outer:
    Console.WriteLine("跳出");

区别:

建议:能用 return/continue 简化就别用 break;别用 goto 除非跳出多层。

八、C# 特有:foreach 与 LINQ 联动

C# 的 foreach 配合 LINQ 能写出非常声明式的代码:

// 传统 for 循环写法
int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var evens = new List<int>();
foreach (int n in nums)
{
    if (n % 2 == 0)
        evens.Add(n);
}

// LINQ + foreach(声明式)
var evens2 = nums.Where(n => n % 2 == 0);
foreach (int n in evens2)
    Console.WriteLine(n);

这只是一个引子,LINQ 后面会单独一篇讲。

九、常见陷阱

小结

控制流是编程的肌肉记忆,语法不难但写好需要练习。记住现代 C# 的写法偏好:多分支用 switch 表达式、遍历集合用 foreach、判空用 is null、避免冗余 == true。下一篇我们看 C# 的方法——把代码组织成可复用的单元。

← 上一篇 C# 运算符

下一篇 C# 方法

✈️💬