yield(C# 참조)yield (C# Reference)

문에 yield 상황별 키워드를 사용하는 경우 해당 메서드, 연산자, 또는 이 키워드가 나타나는 get 접근자가 반복기임을 나타냅니다.When you use the yield contextual keyword in a statement, you indicate that the method, operator, or get accessor in which it appears is an iterator. yield를 사용하여 반복기를 정의할 경우 사용자 지정 컬렉션 형식에 IEnumerator<T>IEnumerable 패턴을 구현하면 명시적 추가 클래스(열거형의 상태를 보관하는 클래스, 예제는 IEnumerator 참조)를 사용하지 않아도 됩니다.Using yield to define an iterator removes the need for an explicit extra class (the class that holds the state for an enumeration, see IEnumerator<T> for an example) when you implement the IEnumerable and IEnumerator pattern for a custom collection type.

다음 예제에서는 두 가지 형태의 yield 문을 보여줍니다.The following example shows the two forms of the yield statement.

yield return <expression>;
yield break;

주의Remarks

yield return 문을 사용하여 각 요소를 따로따로 반환할 수 있습니다.You use a yield return statement to return each element one at a time.

foreach 문 또는 LINQ 쿼리를 이용하여 반복기 메서드를 사용합니다.You consume an iterator method by using a foreach statement or LINQ query. 각각의 foreach 루프의 반복이 반복기 메서드를 호출합니다.Each iteration of the foreach loop calls the iterator method. yield return 문이 반복기 메서드에 도달하면 expression 이 반환되고 코드에서 현재 위치는 유지됩니다.When a yield return statement is reached in the iterator method, expression is returned, and the current location in code is retained. 다음에 반복기 함수가 호출되면 해당 위치에서 실행이 다시 시작됩니다.Execution is restarted from that location the next time that the iterator function is called.

yield break 문을 사용하여 반복기를 종료할 수 있습니다.You can use a yield break statement to end the iteration.

반복기에 대한 자세한 내용은 반복기를 참조하세요.For more information about iterators, see Iterators.

반복기 메서드 및 Get 접근자Iterator methods and get accessors

반복기 선언은 다음과 같은 요구 사항을 충족해야 합니다.The declaration of an iterator must meet the following requirements:

yield 또는 IEnumerable를 반환하는 반복기의 IEnumerator 형식은 object입니다.The yield type of an iterator that returns IEnumerable or IEnumerator is object. 반복기가 IEnumerable<T> 또는 IEnumerator<T>를 반환할 경우 yield return 문의 식 형식에서 제네릭 형식 매개 변수로 암시적 변환이 있어야 합니다.If the iterator returns IEnumerable<T> or IEnumerator<T>, there must be an implicit conversion from the type of the expression in the yield return statement to the generic type parameter .

yield return 또는 yield break 문은 다음과 같은 특징이 있는 메서드에 사용할 수 없습니다.You can't include a yield return or yield break statement in methods that have the following characteristics:

  • 무명 메서드Anonymous methods. 자세한 내용은 무명 메서드를 참조하세요.For more information, see Anonymous Methods.

  • 안전하지 않은 블록을 포함하는 메서드Methods that contain unsafe blocks. 자세한 내용은 unsafe를 참조하세요.For more information, see unsafe.

예외 처리Exception handling

yield return 문은 try-catch 블록에서 찾을 수 없습니다.A yield return statement can't be located in a try-catch block. yield return 문은 try-finally 문의 try 블록에서 찾을 수 있습니다.A yield return statement can be located in the try block of a try-finally statement.

yield break 문은 try 블록이나 catch 블록에서 찾을 수 있지만 finally 블록에서는 찾을 수 없습니다.A yield break statement can be located in a try block or a catch block but not a finally block.

foreach 본문(반복기 메서드 외부)에서 예외를 throw한 경우, 반복기 메서드의 finally 블록이 실행됩니다.If the foreach body (outside of the iterator method) throws an exception, a finally block in the iterator method is executed.

기술 구현Technical implementation

다음 코드는 반복기 메서드에서 IEnumerable<string>을 반환하고 해당 요소를 반복합니다.The following code returns an IEnumerable<string> from an iterator method and then iterates through its elements.

IEnumerable<string> elements = MyIteratorMethod();
foreach (string element in elements)
{
   ...
}

MyIteratorMethod 호출은 메서드의 본문을 실행하지 않습니다.The call to MyIteratorMethod doesn't execute the body of the method. 대신에 IEnumerable<string> 변수에 elements을 반환합니다.Instead the call returns an IEnumerable<string> into the elements variable.

foreach 루프 반복에서 MoveNext에 대한 elements 메서드가 호출됩니다.On an iteration of the foreach loop, the MoveNext method is called for elements. 이 호출은 다음 MyIteratorMethod 문에 도달할 때까지 yield return 본문을 실행합니다.This call executes the body of MyIteratorMethod until the next yield return statement is reached. yield return 문에서 반환하는 식은 루프 본문에서 사용하는 element 변수 값뿐만 아니라 IEnumerable<string>elementsCurrent 속성도 결정합니다.The expression returned by the yield return statement determines not only the value of the element variable for consumption by the loop body but also the Current property of elements, which is an IEnumerable<string>.

이후에 foreach 루프가 반복될 때마다 중지되었던 위치에서 반복기 본문 실행이 계속되고 yield return 문에 도달하면 다시 중지됩니다.On each subsequent iteration of the foreach loop, the execution of the iterator body continues from where it left off, again stopping when it reaches a yield return statement. foreach 루프는 반복기 메서드가 종료되거나 yield break 문에 도달하면 완료됩니다.The foreach loop completes when the end of the iterator method or a yield break statement is reached.

예제Example

다음 예제에는 yield return 루프 내에 for 문이 있습니다.The following example has a yield return statement that's inside a for loop. Main 메서드에서 foreach 문의 본문을 반복할 때마다 Power 반복기 함수에 대한 호출이 생성됩니다.Each iteration of the foreach statement body in the Main method creates a call to the Power iterator function. 반복기 함수를 호출할 때마다 다음에 yield return 루프를 반복하는 도중에 for 문이 실행됩니다.Each call to the iterator function proceeds to the next execution of the yield return statement, which occurs during the next iteration of the for loop.

반복기 메서드의 반환 형식은 반복기 인터페이스 형식인 IEnumerable입니다.The return type of the iterator method is IEnumerable, which is an iterator interface type. 반복기 메서드가 호출되면 숫자의 거듭제곱이 들어 있는 열거형 개체를 반환합니다.When the iterator method is called, it returns an enumerable object that contains the powers of a number.

public class PowersOf2
{
    static void Main()
    {
        // Display powers of 2 up to the exponent of 8:
        foreach (int i in Power(2, 8))
        {
            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
}

예제Example

다음 예제는 반복기인 get 접근자에 대해 설명합니다.The following example demonstrates a get accessor that is an iterator. 이 예제에서는 각 yield return 문이 사용자 정의 클래스의 인스턴스를 반환합니다.In the example, each yield return statement returns an instance of a user-defined class.

public static class GalaxyClass
{
    public static void ShowGalaxies()
    {
        var theGalaxies = new Galaxies();
        foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy)
        {
            Debug.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString());
        }
    }

    public class Galaxies
    {

        public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy
        {
            get
            {
                yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 };
                yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 };
                yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 };
                yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 };
            }
        }

    }

    public class Galaxy
    {
        public String Name { get; set; }
        public int MegaLightYears { get; set; }
    }
}

C# 언어 사양C# language specification

자세한 내용은 C# 언어 사양을 참조하세요.For more information, see the C# Language Specification. C# 언어 사양은 C# 구문 및 사용법에 대한 신뢰할 수 있는 소스입니다.The language specification is the definitive source for C# syntax and usage.

참고 항목See also