[C# 문법] C# yield

1. 참조



2. yeild 키워드

  • C#의 yield 키워드는 호출자(Caller) 에게 컬렉션 데이터를 하나씩 리턴할 때 주로 사용합니다.
  • 흔히 Enumerator(Iterator) 라고 불리우는 이러한 기능은 집합적인 데이터셋으로부터 데이터를 하나씩 호출자에게 보내주는 역할을 합니다.
  • yield는 yield return 또는 yield break 의 2가지 방식으로 주로 사용됩니다.
    • yield return : 컬렉션 데이터를 하나씩 리턴하는데 사용됩니다.
    • yield break : 리턴을 중지하고 Iteration 루프를 빠져나올 때 사용됩니다.


3. yield 사용 예제

3.1 일반 컬렉션 사용 예제

  • 다음은 숫자를 저장하는 컬렉션이 있다고 가정해 보겠습니다.
  • 이제 특정 숫자보다 큰 모든 숫자를 표시하려고 합니다.
  • 먼저, yield 를 사용하지 않은 예제 코드입니다.
using System;
using System.Collections.Generic;

namespace ConsoleApp7
{
    static class Program
    {
        static void Main(string[] args)
        {
            foreach (var nr in GetNumbersGreaterThan3(new List<int> { 1, 2, 3, 4, 5 }))
            {
                Console.WriteLine(nr);
            }
        }

        static IEnumerable<int> GetNumbersGreaterThan3(List<int> numbers)
        {
            var theNumbers = new List<int>();
            foreach (var nr in numbers)
            {
                if (nr > 3)
                    theNumbers.Add(nr);
            }
            return theNumbers;
        }
    }
}

3.2 실행 결과

4
5
  • 위와 같이 코드를 작성해도 아무 문제가 될 요소는 없지만 1가지 단점이 있습니다.
  • 항목을 보관할 중간 목록, 즉 var theNumbers = new List<int> 객체를 생성하였습니다.
  • 객체를 생성함으로써, 리소스량이 증가한다는 단점이 있습니다.
  • 하지만 위와 같은 구조를 yield return 문을 사용하여 중간에 List 객체를 생성하여 사용하는 과정을 피할 수 있습니다.


3.3 yield return 사용 예제

using System;
using System.Collections.Generic;

namespace ConsoleApp7
{
    static class Program
    {
        static void Main(string[] args)
        {
            foreach (var nr in GetNumbersGreaterThan3(new List<int> { 1, 2, 3, 4, 5 }))
            {
                Console.WriteLine(nr);
            }
        }

        static IEnumerable<int> GetNumbersGreaterThan3(List<int> numbers)
        {
            foreach (var nr in numbers)
            {
                if (nr > 3)
                    yield return nr;
            }
        }
    }
}

3.4 실행 결과

4
5
  • yield return 구문을 사용한 결과 이고, 앞서 컬렉션을 사용한 결과와 동일합니다.


4. yield를 사용하기 좋은 경우

  • yield 는 비결정 목록 을 다룰때 유용하게 사용할 수 있습니다.

    비결정 목록 이란? 순회하는 그 시점, 심지어 순회하는 동안에도 원자 목록이 결정되지 않는다는 의미입니다.

    네트워크 데이터로 유사하게 이해하시면 되겠습니다.

  • yield 는 이러한 비결정 데이터(목록)을 순차적 코드의 흐름으로 결정할 수 있게 도와줍니다.
  • yield를 사용하지 않는다면 IEnumerator<T>의 구현체에서 분기문(if 또는 switch)에 들어가서 소스코드가 어려운 부분을 직접 수정 및 이해를 해야 하는 힘든 작업이 될 수 있습니다.
  • 하지만, yield 를 사용하게 되면 목록을 소비하는 쪽과 제공하는 쪽에서 yield return 의 기점으로 구분되기 때문에 코드가 깔끔해 지는 장점이 있습니다.
  • 때문에, 비결정 목록 데이터가 필요한 곳에 yield 키워드를 사용하는 것을 추천 드립니다.
728x90

이 글을 공유하기

댓글

Designed by JB FACTORY