개발/C#

C# yield 기초 이해하기

huiyu 2021. 1. 4. 06:00

yield

호출자(Caller)에게 컬렉션 데이터를 하나씩 리턴할 때 사용한다. Enumerator(Iterator)라고 불리는 이러한 기능은 집합적인 데이터 셋으로부터 데이터를 하나씩 호출자에게 보내주는 역할을 한다.

- yield return : 컬렉션 데이터를 하나씩 리턴하는데 사용
- yield break : 리턴을 중지하고 iteration 루프를 빠져나올 때 사용

예제 1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;
using System.Collections.Generic;
 
class Program
{
    static IEnumerable<int> GetNumber()
    {
        yield return 1;  // 첫번째 루프에서 리턴되는 값
        yield return 2;  // 두번째 루프에서 리턴되는 값
        yield return 3;  // 세번째 루프에서 리턴되는 값
    }
 
    static void Main(string[] args)
    {
        foreach (int num in GetNumber())
        {
            Console.WriteLine(num);
        }
    }
}
cs

출력)
1
2
3

-> 한꺼번에 호출하는게 아닌 한번 호출시마다 다음 yield return을 반환한다.

이러한 방식은 다음과 같은 경우 유용하게 사용한다.

1) 데이터 양이 커서 모든 데이터를 한꺼번에 리턴하는 것보다 조금씩 리턴하는 것이 효과적일 경우
2) 무제한의 데이터를 리턴할 경우, 예를 들어 랜덤 숫자를 무제한 리턴할 경우 전체 리스트를 리턴할 수 없기 때문에 yield를 사용해 구현한다.
3) 모든 데이터를 미리 계산하여 속도가 느린 경우. 한꺼번에 많은 양을 처리할 경우 속도가 느리므로 필요한 값만 리턴하여 사용한다(예 :소수 전체를 구하는 함수. 한꺼번에 모든 데이터를 리턴하는 것보다 계산된 값만 리턴)

yield와 Enumerator

C#에서 yield가 사용되는 곳은 집합적 데이터를 갖고 있는 컬렉션 클래스이다. 일반적으로 컬렉션 클래스는 데이터 요소를 하나씩 사용하기 위해 enumerator(Iterator)를 구현하는데 이떄 yield를 사용하면 된다.

-> yield를 이용하여 컬렉션 데이터를 순차적으로 하나씩 넘겨주는 코드를 구현, 리턴타입으로 IEnumerator 인터페이스를 리턴한다. C#에서 yield를 사용하면 Enumerator 클래스 작성 필요없이 사용가능하다.

예제 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using System;
using System.Collections;
 
public class MyList
{
    private int[] data = { 12345 };
    
    public IEnumerator GetEnumerator()
    {
        int i = 0;
        while (i < data.Length)
        {
            yield return data[i];
            i++;                
        }
    }
 
    //...
}
 
class Program
{
    static void Main(string[] args)
    {
        // foreach 사용하여 Iteration
        var list = new MyList();
 
        foreach (var item in list)  
        {
            Console.WriteLine(item);
        }
 
        // MoveNext를 사용한 수동 Iteration
        IEnumerator it = list.GetEnumerator();
        it.MoveNext();
        Console.WriteLine(it.Current);  // 1
        it.MoveNext();
        Console.WriteLine(it.Current);  // 2
    }
}
cs

MS 예제 -1) IEnumerable return method

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class PowersOf2
{
    static void Main()
    {
        // Display powers of 2 up to the exponent of 8:
        foreach (int i in Power(28))
        {
            Console.Write("{0} ", i);
        }
    }
 
    public static System.Collections.Generic.IEnumerable<int> Power(int number, int exponent)
    {
        int result = 1;
 
        for (int i = 0; i < exponent; i++)
        {
            result = result * number;
            yield return result;
        }
    }
 
    // Output: 2 4 8 16 32 64 128 256
}
cs

MS 예제 -2) get accessor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class PowersOf2
{
    static void Main()
    {
        // Display powers of 2 up to the exponent of 8:
        foreach (int i in Power(28))
        {
            Console.Write("{0} ", i);
        }
    }
 
    public static System.Collections.Generic.IEnumerable<int> Power(int number, int exponent)
    {
        int result = 1;
 
        for (int i = 0; i < exponent; i++)
        {
            result = result * number;
            yield return result;
        }
    }
 
    // Output: 2 4 8 16 32 64 128 256
}
cs

 

참고링크
www.csharpstudy.com/CSharp/CSharp-yield.aspx

 

C# yield - C# 프로그래밍 배우기 (Learn C# Programming)

C# yield C#의 yield 키워드는 호출자(Caller)에게 컬렉션 데이타를 하나씩 리턴할 때 사용한다. 흔히 Enumerator(Iterator)라고 불리우는 이러한 기능은 집합적인 데이타셋으로부터 데이타를 하나씩 호출자

www.csharpstudy.com

docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/yield

 

yield 상황별 키워드 - C# 참조

yield 상황별 키워드 - C# 참조

docs.microsoft.com

 

 

728x90
반응형