C# 循环

`for`、`while`、`do-while`、`foreach`、以及跳转语句。

Beginner
Key Points遍历集合用 `foreach`,需要下标或改元素用 `for`。

四种循环

C#
// for
for (int i = 0; i < 3; i++)
{
    Console.Write(i + " ");
}
Console.WriteLine();

// while
int n = 3;
while (n > 0)
{
    Console.Write(n-- + " ");
}
Console.WriteLine();

// do-while:至少执行一次
int k = 0;
do
{
    Console.Write("执行 ");
} while (k++ < 1);
Console.WriteLine();

// foreach
foreach (var c in "abc")
{
    Console.Write(c + " ");
}
Console.WriteLine();
Output
0 1 2 
3 2 1 
执行 执行 
a b c 

foreach 的细节

C#
var list = new List<int> { 10, 20, 30 };

foreach (var item in list)
{
    Console.Write(item + " ");
}
Console.WriteLine();

// 遍历字典
var map = new Dictionary<string, int> { ["a"] = 1, ["b"] = 2 };
foreach (var (key, value) in map)
{
    Console.Write($"{key}={value} ");
}
Console.WriteLine();

// 遍历时不能修改集合
try
{
    foreach (var item in list)
    {
        list.Add(99);
    }
}
catch (InvalidOperationException)
{
    Console.WriteLine("遍历中修改集合会抛异常");
}
Output
10 20 30 
a=1 b=2 
遍历中修改集合会抛异常
Modifying a collection during foreach throws InvalidOperationException. To delete while iterating, loop backwards with for, or copy via ToList() first.

break 与 continue

C#
for (int i = 1; i <= 6; i++)
{
    if (i % 2 == 0) continue;      // 跳过偶数
    if (i > 5) break;              // 大于 5 就退出
    Console.Write(i + " ");
}
Console.WriteLine();

// goto:跳出多层循环
for (int i = 0; i < 3; i++)
{
    for (int j = 0; j < 3; j++)
    {
        if (i * j == 2)
        {
            Console.WriteLine($"找到 {i} {j}");
            goto done;
        }
    }
}
done:
Console.WriteLine("结束");
Output
1 3 5 
找到 1 2
结束

C# has no labelled break. To escape nested loops use goto, or extract the loop into a method and return — the latter usually reads better.

常见模式

C#
// 倒序
for (int i = 5; i > 0; i--) Console.Write(i + " ");
Console.WriteLine();

// 步长
for (int i = 0; i <= 10; i += 5) Console.Write(i + " ");
Console.WriteLine();

// 无限循环 + 条件退出
int count = 0;
while (true)
{
    if (++count >= 3) break;
}
Console.WriteLine(count);

// LINQ 替代循环
var evens = Enumerable.Range(1, 10).Where(x => x % 2 == 0).ToList();
Console.WriteLine(string.Join(",", evens));
Output
5 4 3 2 1 
0 5 10 
3
2,4,6,8,10

For filter-map style work LINQ is shorter and clearer than a loop. On hot paths (millions per second) hand-written loops still win — LINQ pays delegate and iterator overhead.

Friends & Partners