반복 문

팁 (조언)

이 문서는 이미 하나 이상의 프로그래밍 언어를 알고 있으며 C#을 학습하는 개발자를 위한 기본 사항 섹션의 일부입니다. 프로그래밍을 처음 접하는 경우 먼저 시작 자습서로 시작 하세요. 전체 구문은 언어 참조의 반복 문을 참조하세요.

다른 언어에서 오시겠습니까? 4개의 C# 루프(foreach, while,do-whilefor)는 모두 Java, C++, JavaScript에 직접 동일합니다. 가장 자주 사용하는 것은 foreach입니다. Java 고급 for 또는 JavaScriptfor...of와 같은 인덱스 없이 컬렉션을 반복합니다.

반복 문은 코드 블록을 반복적으로 실행합니다. 블록을 통과하는 각 패스는 반복이며 반복 블록은 루프입니다. C#은 4개의 루프를 제공합니다. 컬렉션에는 foreach부터 시작하고, 조건이 반복을 제어하는 경우에는 whiledo-while를 사용하며, 명시적 인덱스가 필요할 때는 for를 사용합니다.

다음을 사용하여 컬렉션을 반복합니다. foreach

이 문은 foreach 컬렉션의 각 요소에 대해 순서대로 본문을 한 번 실행합니다. 인덱스나 경계 검사를 직접 관리할 필요가 없기 때문에, 컬렉션을 읽을 때 가장 일반적으로 선택되는 방법입니다. foreach 구문은 전형적인 오프바이원 오류를 방지합니다.

string[] names = ["Ana", "Ben", "Cleo"];

// foreach reads each element in order. It's the default loop for
// collections: no index to manage and no off-by-one mistakes.
foreach (string name in names)
{
    Console.WriteLine(name); // => Ana, then Ben, then Cleo
}

foreach는 배열을 포함하여 C#에서 시퀀스로 인식하는 모든 형식과 List<T>함께 작동합니다Dictionary<TKey,TValue>. 이전 예제의 반복 변수name 는 읽기 전용이므로 루프 내에서 다시 할당할 수 없습니다.

루프의 본문은 할당 또는 메서드 호출과 같은 단일 입니다. 블록 문 자체는 0개 이상의 문을 중괄호({ })로 묶는 단일 문입니다.

많은 코딩 표준에서는 단일 문에 대해서도 루프 본문을 중괄호로 묶는 것이 좋습니다. 중괄호는 범위를 명확히 합니다. 이는 흔히 발생하는 실수, 즉 나중에 각 반복마다 실행되리라고 기대하며 두 번째 줄을 추가했지만 실제로는 루프가 끝난 뒤 한 번만 실행되게 되는 실수를 방지합니다. 중괄호만 루프에 속하는 문을 결정합니다. C#은 공백을 중요하게 취급하지 않으므로 들여쓰기만으로는 처리되지 않습니다. 중괄호는 한 줄짜리 문장에도 사용할 수 있습니다. 블록은 루프가 반복 실행하는 하나의 문장입니다. 가독성을 위해 코드를 들여쓰지만 중괄호를 사용하여 블록을 정의합니다.

조건이 유지되는 동안 반복 while

while 루프는 각 반복 전에 부울 조건식을 검사합니다. 조건이 시작 시점에 false이면 본문은 전혀 실행되지 않으므로 while 루프는 0회 이상 실행됩니다.

int countdown = 3;

// A while loop checks its condition before each iteration, so the body
// runs zero or more times.
while (countdown > 0)
{
    Console.WriteLine(countdown); // => 3, then 2, then 1
    countdown--;
}

루프 내부의 무언가가 조건을 변경하는지 확인합니다. 이전 예제 countdown-- 에서는 결국 조건을 false만듭니다. 조건이 절대 false이 되지 않는 루프는 무한히 실행됩니다.

를 사용하여 본문을 한 번 이상 실행합니다. do-while

루프는 do-while 각 반복 후에 해당 상태를 확인하므로 본문은 항상 한 번 이상 실행됩니다. 입력을 묻는 메시지를 표시한 다음 유효성을 검사하는 등 조건을 평가하기 전에 첫 번째 패스가 발생해야 하는 경우 사용합니다.

int attempts = 0;

// A do-while loop runs its body once, then checks the condition. Use it
// when the body must run at least one time.
do
{
    attempts++;
    Console.WriteLine($"Attempt {attempts}"); // => Attempt 1, then Attempt 2, then Attempt 3
}
while (attempts < 3);

개수 for

for 루프 문에는 루프 전에 한 번 실행되는 이니셜라이저, 각 반복 전에 확인된 조건 및 각 반복 후에 실행되는 반복기의 세 부분이 포함됩니다. 요소뿐만 아니라 인덱스 자체가 필요할 때 사용합니다 for . 일반적으로 해당 값을 읽는 대신 요소를 수정하려는 경우 인덱스가 필요합니다.

// A for loop fits when you need an explicit index. The three parts are
// the initializer, the condition, and the iterator.
for (int i = 0; i < 3; i++)
{
    Console.WriteLine(i); // => 0, then 1, then 2
}

요소만 읽고 위치를 사용하지도 새 값을 할당하지도 않을 때는 foreach를 선호하세요. 의도를 보다 명확하게 명시하고 인덱스 산술 연산을 방지합니다.

breakcontinue로 종료 또는 건너뛰기

두 가지 점프 문을 사용하면 어떤 루프 안에서든 더 세밀한 제어가 가능합니다. break 문은 루프를 즉시 종료하고 남아 있는 반복을 모두 건너뜁니다.

int[] numbers = [2, 4, 7, 8];

// break stops the loop immediately, skipping any remaining elements.
foreach (int number in numbers)
{
    if (number % 2 != 0)
    {
        Console.WriteLine($"First odd number: {number}"); // => First odd number: 7
        break;
    }
}

이 문은 continue 현재 반복의 나머지 부분을 건너뛰고 다음 반복으로 이동합니다.

int[] values = [1, 2, 3, 4, 5];

// continue skips the rest of the current iteration and moves to the next.
foreach (int value in values)
{
    if (value % 2 == 0)
    {
        continue; // skip even numbers
    }

    Console.WriteLine(value); // => 1, then 3, then 5
}

await foreach를 사용하여 비동기 스트림 순회하기

비동기 스트림은 비동기 작업을 사용하여 각 다음 요소를 생성하는 판독기입니다. C#은 인터페이스를 IAsyncEnumerable<T> 사용하여 나타냅니다. 웹 API의 페이지 또는 데이터베이스의 행과 같이 시간이 지남에 따라 도착하는 데이터는 이 모델에 적합합니다. 다음 요소를 검색하는 것은 즉시 반환되는 대신 대기 가능한 작업입니다.

비동기 스트림을 사용하려면 키워드await를 앞에 놓습니다foreach. 각 반복은 다음 요소를 대기하므로 해당 요소가 스레드를 차단하는 대신 생성되는 동안 루프가 일시 중단됩니다.

private static async Task AwaitForeachExample()
{
    // await foreach consumes an asynchronous stream. Each iteration can
    // suspend while the next element is produced.
    await foreach (int value in GenerateAsync())
    {
        Console.WriteLine(value); // => 0, then 1, then 2
    }
}

private static async IAsyncEnumerable<int> GenerateAsync()
{
    for (int i = 0; i < 3; i++)
    {
        await Task.Delay(1); // stand-in for real asynchronous work
        yield return i;
    }
}

비동기 스트림은 asyncawait를 기반으로 합니다. 전체 연습은 비동기 스트림 생성 및 사용을 참조하세요.

참고하십시오