yield

Shy·2025년 3월 17일

C#

목록 보기
21/27

yield

yield 키워드는 IEnumerableIEnumerator를 쉽게 구현할 수 있도록 도와주는 기능이다.
보통 foreach 문에서 요소를 하나씩 반환하는데 사용되며, 명시적으로 상태를 관리하지 않아도 자동으로 상태를 기억하면서 다음 요소를 반환할 수 있다.

1. yield return의 기본 동작

예제: yield return 사용

using System;
using System.Collections.Generic;

public class NumberGenerator
{
    // IEnumerable<int>를 반환하는 메서드
    public static IEnumerable<int> GetNumbers()
    {
        yield return 1;  // 첫 번째 값 반환
        yield return 2;  // 두 번째 값 반환
        yield return 3;  // 세 번째 값 반환
    }
}

class Program
{
    static void Main()
    {
        // GetNumbers() 호출 -> IEnumerable<int>을 반환함
        foreach (var num in NumberGenerator.GetNumbers())
        {
            Console.WriteLine(num); // 1, 2, 3 출력
        }
    }
}
// 1
// 2
// 3
  • yield return을 만나면 해당 값을 반환하고, 다음 호출에서 실행이 계속 진행된다.
  • 이전 실행 상태를 자동으로 기억하기 때문에, MoveNext()를 수동으로 구현할 필요가 없다!

2. yield return vs IEumerator 직접 구현 비교

IEnumerator를 직접 구현한 경우

using System;
using System.Collections;
using System.Collections.Generic;

public class CustomEnumerator : IEnumerator<int>
{
    private int[] _numbers = { 1, 2, 3 };
    private int _position = -1;

    public int Current => _numbers[_position];

    object IEnumerator.Current => Current;

    public bool MoveNext()
    {
        _position++;
        return _position < _numbers.Length;
    }

    public void Reset() => _position = -1;

    public void Dispose() { }
}
  • 직접 IEnumerator를 구현하려면 MoveNext(), Current, Reset() 등을 수동으로 관리해야 해서 코드가 복잡하다.

yield return을 사용한 경우

public static IEnumerable<int> GetNumbers()
{
    yield return 1;
    yield return 2;
    yield return 3;
}
  • IEnumerator를 직접 구현할 필요 없이, 간단하게 순차적인 값 반환을 구현할 수 있다.

3. yield break란?

  • yield break반복을 중단하고 즉시 종료하는 역할을 한다.

yield break 사용 예제

using System;
using System.Collections.Generic;

public class NumberGenerator
{
    public static IEnumerable<int> GetNumbers()
    {
        yield return 1;
        yield return 2;
        
        yield break;  // 여기서 즉시 종료됨 (이후 코드 실행 안 됨)

        yield return 3; // 실행되지 않음
    }
}

class Program
{
    static void Main()
    {
        foreach (var num in NumberGenerator.GetNumbers())
        {
            Console.WriteLine(num); // 1, 2만 출력됨
        }
    }
}
  • yield break를 만나면 더 이상 요소를 반환하지 않고 즉시 종료된다.

4. yield return을 활용한 예제

yield return을 이용한 짝수 생성기

using System;
using System.Collections.Generic;

public class EvenNumberGenerator
{
    public static IEnumerable<int> GetEvenNumbers(int start, int count)
    {
        for (int i = 0; i < count; i++)
        {
            yield return start + (i * 2);
        }
    }
}

class Program
{
    static void Main()
    {
        foreach (var num in EvenNumberGenerator.GetEvenNumbers(2, 5))
        {
            Console.WriteLine(num); // 2, 4, 6, 8, 10 출력
        }
    }
}
  • yield return을 사용하면 불필요한 리스트 생성 없이 순차적으로 값이 반환된다.

무한 반복 yield return 사용

using System;
using System.Collections.Generic;

public class InfiniteGenerator
{
    public static IEnumerable<int> GenerateInfiniteNumbers()
    {
        int number = 0;
        while (true)
        {
            yield return number++;
        }
    }
}

class Program
{
    static void Main()
    {
        foreach (var num in InfiniteGenerator.GenerateInfiniteNumbers())
        {
            Console.WriteLine(num);
            if (num >= 5) break; // 0, 1, 2, 3, 4, 5 출력 후 중단
        }
    }
}
  • yield return을 사용하면 불필요한 메모리 할당 없이 필요할 때만 값을 생성할 수 있다.

5. yield return vs return 차이

기능yield returnreturn
반환값여러 개 반환 가능 (순차적)한 번만 반환 후 종료
상태 유지이전 상태를 자동으로 기억상태 유지 X
사용 시점IEnumerable<T> 또는 IEnumerator<T> 사용 시일반적인 메서드에서 사용
// 비교 예제
public static IEnumerable<int> UseYield()
{
    yield return 1;
    yield return 2;
    yield return 3;
}

public static List<int> UseReturn()
{
    return new List<int> { 1, 2, 3 }; // 모든 값을 한 번에 반환
}
// yield return은 하나씩 반환, return은 한 번에 모든 값 반환.

정리

개념설명
yield returnIEnumerable<T>을 쉽게 구현하여 하나씩 반환
yield break반복을 즉시 중단
자동 상태 관리이전 상태를 자동으로 저장 (수동으로 IEnumerator를 구현할 필요 없음)
메모리 최적화모든 데이터를 미리 저장하지 않고, 필요할 때만 생성하여 반환
반복자(iterator) 구현에 유용무한 반복, 데이터 스트리밍 등에서 사용하기 좋음
  • yield return을 사용하면 IEnumerable을 쉽게 구현 할 수 있다.
  • IEnumerator를 직접 구현할 필요 없이 자동으로 상태 관리된다.
  • 메모리 절약과 성능 최적화에 유리 (필요할 때만 값을 생성)
  • 무한 반복이나 데이터 스트리밍 등에 활용할 수 있다.
profile
신입사원...

0개의 댓글