푸터 콘텐츠로 바로가기
.NET 도움말

인덱스와 함께 사용한 C# foreach (개발자를 위한 작동 방식)

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
$vbLabelText   $csharpLabel

이 예에서, number는 각 반복 동안 컬렉션의 요소를 나타냅니다. 루프는 배열의 모든 요소를 자동으로 반복합니다. 그러나 현재 요소의 인덱스에 접근할 수 있는 내장 방법은 없습니다.

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
$vbLabelText   $csharpLabel

이 코드에서는 루프가 시작하기 전에 인덱스 변수를 초기화하고 각 반복 동안 루프 안에서 이를 증가시킵니다. 이 접근 방식은 작동하지만, 인덱스를 수동으로 유지해야 하므로 항상 이상적이지는 않습니다.

방법 2: LINQ의 Select 메서드 사용하기

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
$vbLabelText   $csharpLabel

이 예에서, 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++;
    }
}
Imports System.Collections.Generic

Public Module Extensions
    <System.Runtime.CompilerServices.Extension> 
    Public Iterator Function WithIndex(Of T)(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
    End Function
End Module
$vbLabelText   $csharpLabel

이제 이 확장 메서드를 컬렉션과 함께 사용할 수 있습니다:

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
$vbLabelText   $csharpLabel

이 접근 방식은 수동 인덱스 관리를 재사용 가능한 메서드로 추상화하여 인덱스 문제와 함께 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
$vbLabelText   $csharpLabel

C# 인덱스를 사용한 foreach (개발자를 위한 작동 방식): 그림 1 - 인덱스 출력

이 방법은 인덱스 변수를 배열이나 리스트의 첨자로 사용하여 인덱스와 현재 요소에 직접 액세스할 수 있습니다.

.NET에서 사용자 지정 컬렉션 및 반복기

사용자 지정 컬렉션을 사용하는 경우 인덱스에 액세스를 지원하기 위해 반복기를 구현할 수 있습니다. IEnumerable 인터페이스를 구현하고 yield return 문을 사용함으로써 요소와 인덱스 모두를 반환하는 반복기를 생성할 수 있습니다.

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();
    }
}
Imports System.Collections
Imports System.Collections.Generic

Public Class CustomCollection(Of T)
    Implements IEnumerable(Of T)

    Private _items As T()

    Public Sub New(items As T())
        _items = items
    End Sub

    Public Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator
        For i As Integer = 0 To _items.Length - 1
            Yield _items(i)
        Next
    End Function

    Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
        Return GetEnumerator()
    End Function
End Class
$vbLabelText   $csharpLabel

그러면 이 사용자 지정 컬렉션을 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
$vbLabelText   $csharpLabel

GetEnumerator 메서드를 구현하고 yield return를 사용함으로써 반복기를 생성하여 .NET의 다른 컬렉션처럼 사용자 정의 컬렉션이 foreach 루프에서 작동하도록 할 수 있습니다.

키-값 쌍을 사용하여 사전을 반복하기

사전을 사용할 때 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
$vbLabelText   $csharpLabel

이 예에서, kvp.Key는 현재 키를 제공하고 kvp.Value는 현재 값을 제공합니다.

C# foreach 루프와 인덱스를 사용한 IronPDF

C# 인덱스를 사용한 foreach (개발자를 위한 작동 방식): 그림 2 - IronPDF

IronPDF는 C#에서 HTML로 PDF 생성을 처리하고 PDF 관련 작업을 수행하는 PDF 라이브러리입니다. 최신 .NET Framework와도 호환됩니다. IronPDF를 사용하여 PDF를 생성할 때 데이터 컬렉션을 계속 반복하여 PDF 파일에 콘텐츠를 동적으로 삽입해야 할 수 있습니다. 인덱스 처리와 함께 foreach 루프를 결합하면 현재 요소의 인덱스에 따라 위치 지정, 번호 매기기 또는 사용자 지정 논리를 관리할 수 있습니다. 컬렉션의 각 항목이 인덱스와 함께 문서에 삽입되는 IronPDF를 사용하여 PDF를 생성하는 실용적인 예는 다음과 같습니다.

using IronPdf;
class Program
{
    static void Main(string[] args)
    {
        // Create a new PDF document renderer
        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 renderer
        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 renderer
		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
$vbLabelText   $csharpLabel

여기 출력된 PDF 파일이 있습니다:

C# 인덱스를 사용한 foreach (개발자를 위한 작동 방식): 그림 3 - PDF 출력

결론

C# 인덱스를 사용한 foreach (개발자를 위한 작동 방식): 그림 4 - 라이선스

C#에서는 foreach 루프가 컬렉션을 반복하기에 편리한 방법이지만, 인덱싱에 대한 기본 지원이 부족합니다. 그러나 이러한 제한을 극복 할 수 있는 몇 가지 방법이 있습니다. 단순한 인덱스 변수, LINQ의 Select 메서드, 또는 사용자 정의 반복기를 사용하든 간에 반복 중 현재 또는 다음 요소의 인덱스에 접근할 수 있습니다. 이러한 기술을 이해하면 특히 각 요소의 인덱스를 알아야 할 때 foreach 루프를 더 효율적으로 사용할 수 있습니다.

IronPDF와 함께라면 즉시 커밋할 필요가 없습니다. 소프트웨어의 기능을 깊이 탐색할 수 있는 무료 체험판을 제공합니다. 보시는 것이 마음에 드신다면, 라이선스는 $799부터 시작합니다.

자주 묻는 질문

C# foreach 루프에서 요소의 인덱스를 추적하려면 어떻게 해야 하나요?

C# foreach 루프에서 인덱스를 추적하려면 별도의 인덱스 변수를 수동으로 증가시키거나, LINQ의 Select 메서드를 사용하여 요소와 인덱스를 함께 프로젝트하거나, 요소와 인덱스를 모두 반환하는 사용자 정의 반복자를 만듭니다.

LINQ Select 메서드는 무엇이며 인덱싱에 어떻게 도움이 되나요?

LINQ Select 메서드는 컬렉션의 각 요소를 새로운 형태로 변환하여 요소의 인덱스를 포함시킬 수 있습니다. 이 투영 덕분에 foreach 루프 동안 요소와 인덱스를 모두 액세스할 수 있습니다.

C#에서 인덱싱을 위한 사용자 정의 반복자를 어떻게 만들 수 있나요?

C#에서 yield return 키워드를 사용하여 사용자 정의 반복자를 만들 수 있습니다. 이는 컬렉션을 반복하고 현재 요소와 인덱스를 모두 반환하여 반복문 인덱싱을 단순화하는 메서드를 구축할 수 있게 해줍니다.

PDF 라이브러리를 사용하여 C#에서 인덱스가 있는 콘텐츠를 작성할 수 있나요?

네, IronPDF와 같은 PDF 라이브러리를 C# foreach 루프와 함께 사용하여 데이터 컬렉션을 반복하고 인덱스가 있는 콘텐츠를 PDF에 삽입할 수 있습니다. 이 방법은 동적 콘텐츠 배치와 정확한 인덱싱을 가능하게 합니다.

C#에서 사전을 foreach 루프를 사용하여 어떻게 반복하나요?

C#에서는 foreach 루프가 사전의 각 키-값 쌍에 접근하여 반복할 수 있습니다. 이는 개발자가 반복 과정에서 키와 값을 모두 직접 작업할 수 있게 합니다.

C# 개발에서 PDF 라이브러리를 사용하는 것의 이점은 무엇인가요?

PDF 라이브러리는 개발자가 HTML에서 PDF를 생성하고 C#에서 다양한 PDF 조작을 수행할 수 있게 합니다. 일반적으로 기능을 탐색하기 위한 무료 체험판을 제공하며, 라이센스 구매가 가능합니다.

C#에서 인덱스 반복을 위해 while 루프를 어떻게 사용할 수 있나요?

while 루프는 인덱스 변수를 사용하여 컬렉션을 반복하는 데 사용할 수 있으며, 인덱스를 인덱스로 사용하여 인덱스와 현재 요소 모두에 접근할 수 있게 합니다.

제이콥 멜러, 팀 아이언 최고기술책임자
최고기술책임자

제이콥 멜러는 Iron Software의 최고 기술 책임자(CTO)이자 C# PDF 기술을 개척한 선구적인 엔지니어입니다. Iron Software의 핵심 코드베이스를 최초로 개발한 그는 창립 초기부터 회사의 제품 아키텍처를 설계해 왔으며, CEO인 캐머런 리밍턴과 함께 회사를 NASA, 테슬라, 그리고 전 세계 정부 기관에 서비스를 제공하는 50명 이상의 직원을 보유한 기업으로 성장시켰습니다.

제이콥은 맨체스터 대학교에서 토목공학 학사 학위(BEng)를 최우등으로 취득했습니다(1998~2001). 1999년 런던에서 첫 소프트웨어 회사를 설립하고 2005년 첫 .NET 컴포넌트를 개발한 후, 마이크로소프트 생태계 전반에 걸쳐 복잡한 문제를 해결하는 데 전문성을 발휘해 왔습니다.

그의 대표 제품인 IronPDF 및 Iron Suite .NET 라이브러리는 전 세계적으로 3천만 건 이상의 NuGet 설치 수를 기록했으며, 그의 핵심 코드는 전 세계 개발자들이 사용하는 다양한 도구에 지속적으로 활용되고 있습니다. 25년의 실무 경험과 41년의 코딩 전문성을 바탕으로, 제이콥은 차세대 기술 리더들을 양성하는 동시에 기업 수준의 C#, Java, Python PDF 기술 혁신을 주도하는 데 주력하고 있습니다.

아이언 서포트 팀

저희는 주 5일, 24시간 온라인으로 운영합니다.
채팅
이메일
전화해