paint-brush
C# 中的 foreach 循环 – 初学者指南经过@devleader
838 讀數
838 讀數

C# 中的 foreach 循环 – 初学者指南

经过 Dev Leader10m2024/01/08
Read on Terminal Reader

太長; 讀書

理解 C# 中的 foreach 循环是开发人员的一项基本技能。通过使用 foreach 循环,您可以节省时间,编写更清晰、更简洁的代码,并避免与传统 for 循环相关的常见陷阱。在本文中,我介绍了 C# 中 foreach 循环的基本语法、要避免的常见错误、LINQ 查询和 lambda 等高级技术,以及使用 foreach 循环的最佳实践。
featured image - C# 中的 foreach 循环 – 初学者指南
Dev Leader HackerNoon profile picture

让我们来谈谈掌握 C# 中的 foreach 循环并提高编程效率! Foreach 循环是 C# 编程以及许多其他语言中的一个重要概念。当涉及到集合和数组的迭代时,它们特别有用。


读完本文后,您可以对 foreach 循环的基本语法、要避免的常见错误、要尝试的高级技术以及在自己的项目中有效使用它们的最佳实践有一个深入的了解。


无论您是初学者还是经验丰富的软件工程师,本文都将提供有关如何使用 foreach 循环来简化代码并提高编程技能的宝贵见解。


C# 中 foreach 循环的重要性

Foreach 循环对于在 C# 中使用集合和数组的软件工程师和开发人员至关重要。它们允许使用简单而简洁的语法迭代这些数据结构,从而使使用它们变得更容易、更高效。使用 foreach 循环的主要优点之一是它们比传统的 for 循环复杂性更低。告别范围检查和索引!


For 循环需要使用索引变量,这通常需要额外的声明和赋值。另一方面,foreach 循环在幕后管理索引变量和迭代逻辑,从而减少循环遍历集合或数组所需的代码量。这种简单性导致代码更清晰,更易于阅读和维护。


使用 foreach 循环的另一个好处是更容易调试。由于迭代逻辑被抽象出来,迭代过程中出现的编码错误更容易诊断。当使用 for 循环时,这一点尤其重要,其中可能存在难以识别和解决的差一错误。

C# 中 foreach 循环的基本语法

C# 中 foreach 循环的基本语法如下:

 dataType[] collectionName = new dataType[10]; foreach (dataType variableName in collectionName) { //Execute code for each item in collectionName using variableName as you go. }


dataType 是集合中项目的类型,variableName 是在迭代时分配给集合中当前项目的名称,collectionName 是正在迭代的集合的名称。 'in' 关键字告诉 C# 该循环是一个 foreach 循环,并且对集合中的每个项目执行大括号内的逻辑。


Foreach 循环还可以与 IEnumerable 接口结合使用,该接口提供了一种一次访问集合中的值的方法。使用IEnumerable 接口和 foreach 循环可以减少内存使用量并提高性能,因为它允许开发人员仅在需要时从集合中获取值, 但情况并不总是那么黑白分明


这种方法通常在处理大型数据集时使用,而一次性处理所有数据集是不切实际的。


使用 foreach 循环的常见错误

使用 foreach 循环时,如果开发人员不小心,可能会遇到几个常见错误。请务必注意避免这些错误,因为它们可能会导致难以解决的错误、崩溃和运行时错误。下面讨论了一些最常见的错误,并提供了如何避免和解决这些错误的提示。

迭代期间的修改

一个错误是尝试修改循环期间正在迭代的集合。修改集合可能会导致意外行为,例如无限循环或跳过某些项目。为了避免这种错误,重要的是创建集合的副本以便在需要修改时使用,从而消除在迭代过程中直接修改原始集合的可能性。

空引用

另一个常见错误是在尝试迭代之前不检查空引用。此错误可能会导致空引用异常,从而导致程序崩溃并且难以捕获和解决。在开始迭代过程之前检查空引用是避免此错误的有效方法。

并发修改

并发修改问题也可能令人沮丧,导致不可预测的程序行为和难以重现的缺陷。如果多个线程访问并修改同一个集合,则可能会发生这种情况。开发人员可以通过使用同步集合类或使用锁来确保一次只有一个线程可以修改集合,从而避免并发修改问题。


在 foreach 循环中使用breakcontinue语句

Break 语句在执行时将立即终止循环,无论集合是否已完成迭代。或者, continue 语句将立即进入循环的下一次迭代,跳过当前迭代中的剩余代码行。这些语句可用于简化错误检查并提高代码可读性。


例如,当在集合中搜索特定项目时,break 语句非常有用,并且一旦找到该项目就可以停止循环。如果使用得当,break 和 continue 语句可以降低代码的复杂性,提高其性能,并使其更易于遵循和理解。


查看此代码以获取 break 关键字的示例。

 Item? foundItem = null; foreach (var item in collection) { if (item.Name == "Dev Leader") { foundItem = item; break; } }

foreach 循环的高级技术

当您越来越习惯在 C# 中使用 foreach 循环时,他们可能想要探索一些可用的高级技术。 foreach 循环的高级技术有助于进一步优化代码并提高性能。本节将探讨多种高级技术,包括 LINQ 查询和 lambda、枚举和过滤以及并行化。


每个主题都值得用自己的完整文章来讨论。

循环内的 LINQ 和 Lambda 表达式

一项高级技术是将 LINQ 查询和 lambda 与 foreach 循环结合使用。 LINQ 允许开发人员编写更简洁、更具表现力的代码。可以使用 LINQ 语法编写查询,并且可以使用 lambda 直接在循环内过滤、排序和操作数据,从而减少后续循环的需要。


让我们看一个例子:

 public sealed record Item( int Id, string Name, DateTime CreatedDateTimeUtc); // Use .Select() from LINQ to change what we're operating on foreach (var item in collection.Select(x => new { Id = x.Id, Name = x.Name })) { if (item.Name == "Dev Leader") { // we're only interested in the ID, so return it! return item.Id; } }

过滤

另一种技术是枚举和过滤,这有助于减少大型数据集的内存占用。该技术允许仅生成与当前操作相关并且满足特定标准的数据子集。这在处理大型数据集时非常有用,因为它避免了立即处理整个数据集的需要,这可能非常耗时并且可能导致性能问题。


我们来看一个代码示例:

 public sealed record Item( int Id, string Name, DateTime CreatedDateTimeUtc); // Put the filtering right in the foreach line by using .Where() from LINQ foreach (var item in collection.Where(x => x.Name == "Dev Leader")) { // we're only interested in the ID, so return it! return item.Id; }

并行化

并行化是另一种可以与 foreach 循环一起使用的高级技术。并行化 foreach 循环可以是利用多核处理器并提高性能的一种方法。并行化可以通过使用并行 LINQ 运算符 PLINQ 来实现,它可以将迭代过程分成更小的部分并在单独的线程上执行它们。


我们还可以使用Parallel.ForeachParallel.ForeachAsync之类的东西,甚至可以将工作拆分为专用任务并使用Task.WhenAll()等待结果。在研究这些选项时,您可能有兴趣观看此视频以了解一些性能差异


将 LINQ 与 foreach 循环结合使用

LINQ(即语言集成查询)是C# 中强大的语言功能,它允许开发人员以更具表现力和更高效的方式与各种数据源进行交互。将 LINQ 查询与 foreach 循环结合使用的能力可以简化代码并降低复杂性,使代码更具可读性和可维护性。


要将 LINQ 与 foreach 循环结合使用,查询将在循环外部执行并保存到变量中。然后使用 foreach 循环迭代查询变量。常见的 LINQ 查询包括OrderByWhere() ,前者按升序或降序对数据进行排序,后者返回满足特定条件的项目子集。可以使用 lambda 表达式编写自定义 LINQ 查询,从而允许开发人员以有意义的方式操作数据。


在 C# 中使用 foreach 循环的最佳实践

在 C# 中使用 foreach 循环时,需要牢记一些最佳实践。通过遵循这些实践,开发人员可以确保他们的代码高效且可维护,没有错误,并且符合行业标准。下面讨论一些最重要的最佳实践。

选择适当的数据类型

选择要迭代的适当数据类型是使用 foreach 循环的重要最佳实践。某些数据类型(例如列表和数组)更适合 foreach 循环,而其他数据类型(例如哈希表)可能效率不高。在选择要迭代的适当数据类型时,考虑数据结构和存储的数据类型非常重要。


在 dotnet 的最新版本中(在撰写本文时!),数组和列表的性能得到了一些令人难以置信的提升。从历史上看,foreach 循环的性能可能不如带有索引器的 for 循环。然而,dotnet 团队已经发挥了一些魔力!我强烈建议您观看此视频以了解一些性能详细信息

尽可能使用只读集合

使用 foreach 循环时,尽可能使用只读集合是另一个重要的最佳实践。只读集合有助于防止迭代过程中数据结构的修改,从而降低出错的风险。如果需要修改,最好制作集合的副本并使用副本,而不是修改原始集合。


解决枚举过程中集合被修改的问题是一件非常痛苦的事情。

保持代码简单

保持代码简单并避免不必要的复杂性是另一个可以节省时间并减少错误的最佳实践。代码应保持干净、可读,结构清晰、逻辑清晰、易于理解。这可以通过使用描述性变量名称以及将代码分组为函数和类来实现。


我发现我们作为程序员倾向于使用我们拥有的某些 LINQ 选项。结果有时是我们有这些复杂的链式 LINQ 查询,它们可以做一些很棒的事情,但是……它们很难阅读。在尝试过滤和操作数据时请记住这一点。

避免过早优化

避免过早优化是使用 foreach 循环的另一个重要方面。开发人员在清楚了解需要优化的内容之前应该避免优化代码。过早优化代码可能会导致缺乏清晰度,并可能导致回归错误。


还记得本文前面关于并行性的要点吗?如果您刚刚开始……不要在这些事情上浪费时间。了解基础知识。在进入更高级的方面之前先打好坚实的基础。

使用简洁且具有描述性的变量名称

在使用 foreach 循环时,使用简洁且具有描述性的变量名称是另一个重要的最佳实践。变量名称应该简短且具有描述性,并且应该反映变量的用途。这有助于提高代码的可读性,使代码更容易理解。


这个技巧是专门针对 foreach 循环的吗?绝对不。但它在编程中非常重要,因此我将继续寻找方法将其融入其中,以提醒人们可读代码的重要性。

正确的错误检查和异常处理

使用 foreach 循环时,正确的错误检查和异常处理是至关重要的最佳实践。错误检查应包含在整个代码中,特别是在使用集合和数组时。迭代过程中抛出的任何异常都应该使用 try-catch 语句正确处理。这有助于防止程序崩溃并提高代码的可维护性。


总结 C# 中的 foreach 循环

理解 C# 中的 foreach 循环是开发人员的一项基本技能。通过使用 foreach 循环,您可以节省时间,编写更清晰、更简洁的代码,并避免与传统 for 循环相关的常见陷阱。在本文中,我介绍了 C# 中 foreach 循环的基本语法、要避免的常见错误、LINQ 查询和 lambda 等高级技术,以及使用 foreach 循环的最佳实践。


请记住始终选择适当的数据类型进行迭代,尽可能使用只读集合,并保持代码简单明了。通过练习和应用,您可以更好地编写 C# 最常用的工具之一。


我希望您在本文中找到有用的东西!如果您对更多学习机会感兴趣,请订阅我的免费每周时事通讯


也发布在这里