C# for/foreach 循环(长文解析)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

前言

在编程的世界中,循环是解决问题的核心工具之一。无论是遍历数据、重复执行任务,还是构建复杂算法,循环都能帮助开发者高效地完成工作。在 C# 中,forforeach 循环是最常用的两种循环结构。对于编程初学者而言,理解它们的语法、差异和使用场景至关重要;而中级开发者则可以通过深入学习它们的高级技巧,进一步提升代码的简洁性和性能。本文将从基础到进阶,结合实际案例,系统讲解 C# for/foreach 循环的用法与最佳实践。


基础语法:for 循环

1. 核心结构与执行逻辑

for 循环适用于已知循环次数的场景。其语法结构如下:

for (初始化表达式; 条件判断; 迭代表达式)  
{  
    // 循环体  
}  
  • 初始化表达式:通常用于定义循环变量(如 int i = 0)。
  • 条件判断:每次循环前判断是否满足条件,若为 false,循环终止。
  • 迭代表达式:在每次循环结束后更新循环变量(如 i++)。

示例:遍历 0 到 4 的整数:

for (int i = 0; i < 5; i++)  
{  
    Console.WriteLine(i);  
}  
// 输出:0 1 2 3 4  

2. 形象比喻:像按计划旅行

可以将 for 循环想象为一次有明确路线的旅行:

  • 初始化表达式 = 出发前准备行李;
  • 条件判断 = 检查是否到达终点;
  • 迭代表达式 = 每天前进固定距离。

foreach 循环:专为集合设计

1. 核心语法与适用场景

foreach 循环专门用于遍历 集合或数组,其语法简洁直观:

foreach (var element in collection)  
{  
    // 处理 element  
}  
  • element:每次循环中代表集合中的一个元素。
  • collection:需要遍历的数组或实现了 IEnumerable 接口的集合(如 List<T>)。

示例:遍历字符串数组:

string[] fruits = { "Apple", "Banana", "Cherry" };  
foreach (string fruit in fruits)  
{  
    Console.WriteLine(fruit);  
}  
// 输出:Apple Banana Cherry  

2. 形象比喻:跟着导游的旅行

foreach 循环就像跟随导游游览景点:

  • 导游(集合):负责管理路线和元素顺序;
  • 游客(循环代码):只需关注当前景点(元素),无需关心如何移动到下一个位置。

for 与 foreach 的核心差异

对比维度for 循环foreach 循环
适用场景已知循环次数或需要精确控制索引遍历集合或数组,无需索引
索引控制可直接访问索引(如 array[i]无法直接获取索引,需通过额外变量实现
修改集合可能引发异常(如修改集合的大小)直接修改集合会抛出 InvalidOperationException
代码简洁性需手动管理变量,代码略显冗长语法简洁,适合快速遍历

进阶用法与技巧

1. 嵌套循环:构建多维结构

嵌套循环可以处理矩阵、表格等多维数据。例如,遍历一个二维数组:

int[,] matrix = {  
    { 1, 2 },  
    { 3, 4 },  
    { 5, 6 }  
};  
for (int i = 0; i < matrix.GetLength(0); i++)  
{  
    for (int j = 0; j < matrix.GetLength(1); j++)  
    {  
        Console.Write(matrix[i, j] + " ");  
    }  
    Console.WriteLine();  
}  
// 输出:1 2  
//       3 4  
//       5 6  

2. 提前终止循环:break 与 continue

  • break:立即跳出整个循环;
  • continue:跳过当前迭代,进入下一次循环。
// 使用 break 示例  
for (int i = 0; i < 10; i++)  
{  
    if (i == 5) break;  
    Console.Write(i + " ");  
}  
// 输出:0 1 2 3 4  

3. foreach 的局限性与解决方案

如果需要在 foreach 中获取元素的索引,可以通过以下方式实现:

string[] colors = { "Red", "Green", "Blue" };  
for (int index = 0; index < colors.Length; index++)  
{  
    Console.WriteLine($"索引 {index}: {colors[index]}");  
}  
// 或者使用 LINQ 的 Select 方法:  
foreach (var pair in colors.Select((value, index) => new { value, index }))  
{  
    Console.WriteLine($"索引 {pair.index}: {pair.value}");  
}  

实际案例与性能对比

1. 案例 1:计算斐波那契数列

// 使用 for 循环计算前 10 项斐波那契数列  
int n = 10;  
int[] fibonacci = new int[n];  
fibonacci[0] = 0;  
fibonacci[1] = 1;  
for (int i = 2; i < n; i++)  
{  
    fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2];  
}  
foreach (int num in fibonacci)  
{  
    Console.Write(num + " ");  
}  
// 输出:0 1 1 2 3 5 8 13 21 34  

2. 案例 2:处理订单数据

假设有一个订单列表,需要筛选出总价超过 1000 元的订单:

List<Order> orders = GetOrders();  
foreach (Order order in orders)  
{  
    if (order.TotalPrice > 1000)  
    {  
        Console.WriteLine($"订单 {order.Id} 总价为 {order.TotalPrice:C}");  
    }  
}  

3. 性能对比:for 与 foreach 的效率

  • for 循环:直接操作内存地址,通常更快,适合对性能要求高的场景;
  • foreach 循环:通过迭代器实现,开销略高,但代码更清晰,适合简单遍历。

测试代码示例

int[] largeArray = new int[1000000];  
Stopwatch sw = new Stopwatch();  

// 测试 for 循环  
sw.Start();  
for (int i = 0; i < largeArray.Length; i++)  
{  
    // 空操作  
}  
sw.Stop();  
Console.WriteLine($"for 循环耗时:{sw.ElapsedMilliseconds} ms");  

// 测试 foreach 循环  
sw.Restart();  
foreach (var _ in largeArray)  
{  
    // 空操作  
}  
sw.Stop();  
Console.WriteLine($"foreach 循环耗时:{sw.ElapsedMilliseconds} ms");  

(注:实际性能可能因环境而异,需结合具体场景选择。)


最佳实践与总结

1. 选择循环的黄金法则

  • for:当需要精确控制索引、处理固定次数的任务,或对性能要求严格时;
  • foreach:当只需遍历集合元素,且无需修改集合或索引时。

2. 避免常见陷阱

  • 修改集合:在 for 循环中修改集合(如删除元素)可能导致索引错误,需谨慎处理;
  • 迭代器失效:在 foreach 中直接修改集合会抛出异常,可考虑先复制为临时列表。

3. 结论

掌握 C# for/foreach 循环是成为高效 C# 开发者的必经之路。通过理解两者的语法差异、性能特点和适用场景,开发者可以编写出既清晰又高效的代码。无论是构建基础功能还是优化复杂逻辑,合理选择循环结构都能显著提升开发效率。

希望本文能帮助你更好地驾驭 C# 的循环工具,让代码在简洁与性能之间找到最佳平衡点!

最新发布