.NET 帮助

C# foreach with index(如何为开发人员工作)

发布 2024年十月23日
分享:

在 C# 中foreach语句迭代 "通常用于迭代数组、列表或其他可枚举类型等集合。然而,foreach 循环的一个局限是没有提供内置索引变量来跟踪当前迭代。 开发人员经常需要访问当前元素的索引。 下面,我们将探讨实现这一功能的各种方法以及IronPDF 库.

foreach 循环的基础知识

foreach 循环旨在简化数组、列表、字典和其他实现 IEnumerable 的类型的迭代过程。 下面是一个基本示例,说明如何使用 foreach 语句在整数数据类型的数组中循环:

int[] numbers = { 10, 20, 30, 40 };
foreach (int number in numbers)
{
    Console.WriteLine(number);
}
int[] numbers = { 10, 20, 30, 40 };
foreach (int number in numbers)
{
    Console.WriteLine(number);
}
Dim numbers() As Integer = { 10, 20, 30, 40 }
For Each number As Integer In numbers
	Console.WriteLine(number)
Next number
VB   C#

在本例中,数字代表每次迭代时集合的元素。 循环自动遍历数组中的所有元素。 然而,没有访问当前元素索引的内置方法。

在 foreach 循环中处理索引

虽然 C# 不能直接在 foreach 循环中提供索引,但有几种技术可以解决这个问题。 让我们详细讨论一下这些方法。

方法 1:使用单独的变量

获取当前元素索引的最简单方法之一是使用外部索引变量。 您需要在循环内手动递增:

int[] numbers = { 10, 20, 30, 40 };
int numberIndex = 0;
foreach (int number in numbers)
{
    Console.WriteLine($"Index: {numberIndex}, Value: {number}");
    numberIndex++;
}
int[] numbers = { 10, 20, 30, 40 };
int numberIndex = 0;
foreach (int number in numbers)
{
    Console.WriteLine($"Index: {numberIndex}, Value: {number}");
    numberIndex++;
}
Dim numbers() As Integer = { 10, 20, 30, 40 }
Dim numberIndex As Integer = 0
For Each number As Integer In numbers
	Console.WriteLine($"Index: {numberIndex}, Value: {number}")
	numberIndex += 1
Next number
VB   C#

在这段代码中,索引变量在循环开始前初始化,然后在每次迭代时在循环内部递增。 虽然这种方法可行,但需要手动维护索引,这并不总是理想的选择。

方法 2:使用 LINQ 的选择方法

LINQ 的 Select 方法可用于将集合中的每个元素(包括其索引)投射到一个新的表单中。 这里有一个例子:

int[] numbers = { 10, 20, 30, 40 };
foreach (var item in numbers.Select((value, index) => new { value, index }))
{
    Console.WriteLine($"Index: {item.index}, Value: {item.value}");
}
int[] numbers = { 10, 20, 30, 40 };
foreach (var item in numbers.Select((value, index) => new { value, index }))
{
    Console.WriteLine($"Index: {item.index}, Value: {item.value}");
}
Dim numbers() As Integer = { 10, 20, 30, 40 }
For Each item In numbers.Select(Function(value, index) New With {
	Key value,
	Key index
})
	Console.WriteLine($"Index: {item.index}, Value: {item.value}")
Next item
VB   C#

在本例中,Select 创建了一个匿名对象,其中包含当前元素的值及其索引。 然后,foreach 循环可以遍历这些对象,并直接访问索引和值。

方法 3:使用自定义迭代器

您可以使用 yield return 关键字实现自定义迭代器扩展方法,生成一个既能生成当前元素又能生成其索引的方法。 这有点高级,但提供了一个灵活的解决方案。

public static IEnumerable<(int index, T value)> WithIndex<T>(this IEnumerable<T> source)
{
    int index = 0;
    foreach (T value in source)
    {
        yield return (index, value);
        index++;
    }
}
public static IEnumerable<(int index, T value)> WithIndex<T>(this IEnumerable<T> source)
{
    int index = 0;
    foreach (T value in source)
    {
        yield return (index, value);
        index++;
    }
}
<System.Runtime.CompilerServices.Extension> _
Public Function WithIndex(Of T)(ByVal source As IEnumerable(Of T)) As IEnumerable(Of (index As Integer, value As T))
	Dim index As Integer = 0
	For Each value As T In source
		Yield (index, value)
		index += 1
	Next value
End Function
VB   C#

现在,您可以将这种扩展方法用于您的作品集:

int[] numbers = { 10, 20, 30, 40 };
foreach (var (index, value) in numbers.WithIndex())
{
    Console.WriteLine($"Index: {index}, Value: {value}");
}
int[] numbers = { 10, 20, 30, 40 };
foreach (var (index, value) in numbers.WithIndex())
{
    Console.WriteLine($"Index: {index}, Value: {value}");
}
Dim numbers() As Integer = { 10, 20, 30, 40 }
foreach var(index, value) In numbers.WithIndex()
	Console.WriteLine($"Index: {index}, Value: {value}")
Next
VB   C#

这种方法通过将手动索引管理抽象为一种可重用的方法,为带索引的 foreach 问题提供了一种更优雅的解决方案。

使用 while 循环访问索引

如果您正在处理数组或列表等集合,您可以将 while 循环与索引变量结合使用,以访问索引和当前元素:

int[] numbers = { 10, 20, 30, 40 };
int index = 0;
while (index < numbers.Length)
{
    Console.WriteLine($"Index: {index}, Value: {numbers[index]}");
    index++;
}
int[] numbers = { 10, 20, 30, 40 };
int index = 0;
while (index < numbers.Length)
{
    Console.WriteLine($"Index: {index}, Value: {numbers[index]}");
    index++;
}
Dim numbers() As Integer = { 10, 20, 30, 40 }
Dim index As Integer = 0
Do While index < numbers.Length
	Console.WriteLine($"Index: {index}, Value: {numbers(index)}")
	index += 1
Loop
VB   C#

C# foreach 带索引(How It Works For Developers):图 1 - 索引输出

通过使用索引变量作为数组或列表的下标,这种方法可以直接访问索引和当前元素。

.NET中的自定义集合和迭代器

如果您正在使用自定义集合,您可以实现迭代器以支持索引访问。 通过实现 IEnumerable 接口并使用 yield 返回语句,您可以创建同时返回元素及其索引的迭代器。

下面是创建实现 IEnumerable 的自定义集合的示例:

public class CustomCollection<T> : IEnumerable<T>
{
    private T[] _items;
    public CustomCollection(T[] items)
    {
        _items = items;
    }
    public IEnumerator<T> GetEnumerator()
    {
        for (int i = 0; i < _items.Length; i++)
        {
            yield return _items[i];
        }
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
public class CustomCollection<T> : IEnumerable<T>
{
    private T[] _items;
    public CustomCollection(T[] items)
    {
        _items = items;
    }
    public IEnumerator<T> GetEnumerator()
    {
        for (int i = 0; i < _items.Length; i++)
        {
            yield return _items[i];
        }
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
Public Class CustomCollection(Of T)
	Implements IEnumerable(Of T)

	Private _items() As T
	Public Sub New(ByVal items() As T)
		_items = items
	End Sub
	Public Iterator Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator
		For i As Integer = 0 To _items.Length - 1
			Yield _items(i)
		Next i
	End Function
	Private Iterator Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
		Return GetEnumerator()
	End Function
End Class
VB   C#

然后,您可以在 foreach 循环中使用该自定义集合:

var customCollection = new CustomCollection<int>(new int[] { 10, 20, 30, 40 });
foreach (int number in customCollection)
{
    Console.WriteLine(number);
}
var customCollection = new CustomCollection<int>(new int[] { 10, 20, 30, 40 });
foreach (int number in customCollection)
{
    Console.WriteLine(number);
}
Dim customCollection As New CustomCollection(Of Integer)(New Integer() { 10, 20, 30, 40 })
For Each number As Integer In customCollection
	Console.WriteLine(number)
Next number
VB   C#

通过实现 GetEnumerator 方法并使用 yield return,您可以创建一个迭代器,使 foreach 循环可以像 .NET 中的其他集合一样使用自定义集合。

使用字典和键值对迭代

在处理字典时,foreach 循环允许您直接遍历键值对。 这是在每次迭代中访问键和值的常见用例:

Dictionary<int, string> dict = new Dictionary<int, string>
{
    { 1, "Apple" },
    { 2, "Banana" },
    { 3, "Cherry" }
};
foreach (var kvp in dict)
{
    Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
}
Dictionary<int, string> dict = new Dictionary<int, string>
{
    { 1, "Apple" },
    { 2, "Banana" },
    { 3, "Cherry" }
};
foreach (var kvp in dict)
{
    Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
}
Dim dict As New Dictionary(Of Integer, String) From {
	{1, "Apple"},
	{2, "Banana"},
	{3, "Cherry"}
}
For Each kvp In dict
	Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}")
Next kvp
VB   C#

在本例中,kvp.Key 表示当前键值,kvp.Value 表示当前值。

使用 IronPdf 与 C# foreach 循环和索引

C# foreach with index(如何为开发人员工作):图 2 - IronPdf

IronPDF 是一个 PDF 库,用于处理从 HTML 生成 PDF以及 C# 中与 PDF 相关的其他任务。 它还与最新的 .NET Framework 兼容。 使用 IronPDF 生成 PDF 时,您可能需要遍历数据集合,并将内容动态插入 PDF 文件。将 foreach 循环与索引处理相结合,您就可以根据集合中当前项目的索引来管理定位、编号或自定义逻辑。 下面是一个使用 IronPDF 创建 PDF 的实用示例,其中集合中的每个项目都连同其索引一起插入到文档中。

using IronPdf;
class Program
{
    static void Main(string[] args)
    {
        // Create a new PDF document
        var pdf = new ChromePdfRenderer();
        // Sample data array
        string[] items = { "First Item", "Second Item", "Third Item" };
        // Initialize the HTML content with foreach loop and index
        string htmlContent = "<html><body>";
        int index = 0;
        foreach (var item in items)
        {
            htmlContent += $"<h2>Item {index + 1}: {item}</h2>";
            index++;
        }
        htmlContent += "</body></html>";
        // Render the HTML to PDF
        var pdfDocument = pdf.RenderHtmlAsPdf(htmlContent);
        // Save the PDF document
        pdfDocument.SaveAs("output.pdf");
        // Notify completion
        Console.WriteLine("PDF created successfully with indexed items.");
    }
}
using IronPdf;
class Program
{
    static void Main(string[] args)
    {
        // Create a new PDF document
        var pdf = new ChromePdfRenderer();
        // Sample data array
        string[] items = { "First Item", "Second Item", "Third Item" };
        // Initialize the HTML content with foreach loop and index
        string htmlContent = "<html><body>";
        int index = 0;
        foreach (var item in items)
        {
            htmlContent += $"<h2>Item {index + 1}: {item}</h2>";
            index++;
        }
        htmlContent += "</body></html>";
        // Render the HTML to PDF
        var pdfDocument = pdf.RenderHtmlAsPdf(htmlContent);
        // Save the PDF document
        pdfDocument.SaveAs("output.pdf");
        // Notify completion
        Console.WriteLine("PDF created successfully with indexed items.");
    }
}
Imports IronPdf
Friend Class Program
	Shared Sub Main(ByVal args() As String)
		' Create a new PDF document
		Dim pdf = New ChromePdfRenderer()
		' Sample data array
		Dim items() As String = { "First Item", "Second Item", "Third Item" }
		' Initialize the HTML content with foreach loop and index
		Dim htmlContent As String = "<html><body>"
		Dim index As Integer = 0
		For Each item In items
			htmlContent &= $"<h2>Item {index + 1}: {item}</h2>"
			index += 1
		Next item
		htmlContent &= "</body></html>"
		' Render the HTML to PDF
		Dim pdfDocument = pdf.RenderHtmlAsPdf(htmlContent)
		' Save the PDF document
		pdfDocument.SaveAs("output.pdf")
		' Notify completion
		Console.WriteLine("PDF created successfully with indexed items.")
	End Sub
End Class
VB   C#

下面是输出的 PDF 文件:

C# foreach 带索引(How It Works For Developers):图 3 - PDF 输出

结论

带索引的 C# foreach(《如何为开发人员工作》):图 4 - 许可

在 C# 中,虽然foreach 循环是遍历集合的便捷方法,但它缺乏对索引的本地支持。 不过,有几种方法可以克服这一限制。 无论是使用简单的索引变量、LINQ 的 Select 方法还是自定义迭代器,您都可以在迭代过程中访问当前或下一个元素的索引。 了解这些技术可以帮助您更有效地使用 foreach 循环,尤其是当您需要知道每个元素的索引时。

有了 IronPdf,您不必立即投入工作。 我们提供免费试用此外,译文还应让您深入了解软件的功能。 如果您喜欢,许可证起价为 749 美元。

< 前一页
C# 索引器(如何为开发人员工作)
下一步 >
Socket io .NET(其对开发人员的工作原理)

准备开始了吗? 版本: 2024.12 刚刚发布

免费NuGet下载 总下载量: 11,781,565 查看许可证 >