1. Introduction
for
,foreach
문은 이하 블록을 반복 실행한다.for
,foreach
의 실행 차이점은 아래와 같다.for
: 주어진 조건식이true
일 때 실행foreach
: 주어진 컬렉션 전체 실행
- 반복문에서는 break 문, continue 문을 통해 반복 중단 또는 다음 반복 실행을 할 수 있다.
2. for
문
for
문은 주어진 조건식이true
일 때 블록을 실행한다.for
문의 구성은 아래와 같다.for ( initializer; condition; iterator) { }
for
문의condition
을 제외한 각 섹션에는 여러 개의 식이 포함될 수 있다.initializer
: 루프 변수를 선언하지 않는 경우 여러 개의 식 사용 가능
2.1. Example
가장 간단한
for
문의 형태는 아래와 같다.for (int i = 0; i < 5; i++) { Console.WriteLine(i); } /* output: 0 1 2 3 4 */
각 섹션에 여러 개의 식이 포함될 수 있다는 특성을 이용하여 아래와 같이
for
문을 구성할 수도 있다.int first = 1, last = 1, fibonacci = 0; for (Console.WriteLine("Start - "), Console.WriteLine($"first : {first}, last : {last}, fibonacci : {fibonacci}"); fibonacci < 50; first = last, last = fibonacci, Console.WriteLine($"fibonacci : {fibonacci}")) { fibonacci = first + last; } /* output: Start - first : 1, last : 1, fibonacci : 0 fibonacci : 2 fibonacci : 3 fibonacci : 5 fibonacci : 8 fibonacci : 13 fibonacci : 21 fibonacci : 34 fibonacci : 55 */
3. foreach
문
foreach
문은 컬렉션의 요소를 반복하여 실행한다.- IEnumerable, IEnumerable<T>, Span<T> 등을 지원한다.
- 구체적으로
foreach
문이 지원하는 형식은 아래와 같다.GetEnumerator
메서드 구현GetEnumerator
메서드의 반환 형식이 IEnumerator를 구현GetEnumerator
메서드의 반환 형식이public Current
속성과bool
을 반환하는MoveNext
메서드를 구현
foreach
문의 구성은 아래와 같다.foreach(T item in collection) { }
item
collection
의 각 요소
collection
- 요소를 반복하여 실행할 컬렉션
3.1. Example
간단한
foreach
문의 형태는 다음과 같다.List<char> chars = ['H', 'E', 'L', 'L', 'O']; foreach(char item in chars) { Console.Write(item); } /* output: HELLO */
다음과 같이
foreach
문을 실행할 컬렉션이 비어있는 경우, 실행하지 않고 건너뛴다.List<char> chars = []; foreach (char item in chars) { Console.Write("A"); } /* output: */
GetEnumerator
메서드 반환 형식의Current
속성이 ref 형식인 경우 반복 변수에ref
한정자를 사용할 수 있다.Span<int> ints = [1, 2, 3]; foreach (ref int item in ints) { item++; } Console.WriteLine(string.Join(", ", ints.ToArray())); /* output: 2, 3, 4 */
var 키워드를 이용하여
foreach
문에서 반복 변수의 형식을 유추할 수도 있다.List<char> chars = ['H', 'E', 'L', 'L', 'O']; foreach (var item in chars) { Console.Write(item); } /* output: HELLO */
3.2. await foreach
await
연산자를foreach
문에 적용하여 컬렉션을 비동기적으로 접근할 수 있다.기본적으로 각 요소는 진입 컨텍스트에서 처리된다.
작업 컨텍스트를 유지하고 싶다면, ConfigureAwait 메서드의continueOnCapturedContext
를false
로 설정하여 진입 컨텍스트로 돌아오지 않을 수 있다.await foreach
문이 지원하는 형식은 다음과 같다.- IAsyncEnumerable<T>를 구현하는 형식
GetAsyncEnumerator
메서드를 구현한 형식- 반환 형식이
public Current
속성 구현 - 반환 형식의
MoveNextAsync
메서드가 Task<bool>, ValueTask<bool>을 반환하거나 awaiter의GetResult
메서드가bool
을 반환
- 반환 형식이
await foreach
문은 아래와 같이 사용한다.public async Task AwaitForeach() { await foreach(var response in GetResponseAsync()) { Console.WriteLine(response); } } public async IAsyncEnumerable<HttpResponseMessage> GetResponseAsync(List<HttpRequestMessage> messages) { foreach (var message in messages) { var rtn = await client.SendAsync(message); yield return rtn; } }