Share via


yield (C# リファレンス)

ステートメントで yield のキーワードを使用すると、表示 get のメソッド、演算子、またはアクセサーが反復子であることを示します。コレクションに対するカスタムのイテレーションを実行するために反復子を使用します。次の例では yield のステートメントの 2 とおりの形式を次に示します。

yield return <expression>;
yield break;

解説

各要素を一つずつ返すために yield return ステートメントを使用します。

foreach のステートメントまたは LINQ クエリを使用して、反復子のメソッドを実装します。foreach ループの各反復で反復子のメソッドを呼び出します。yield return ステートメントが反復子のメソッドに到達すると、expression は戻り、コードの現在の位置は保持されます。実装はその位置から反復子関数が呼び出されると、に再起動されます。

イテレーションの末尾に yield break ステートメントを使用できます。

反復子の詳細については、「反復子 (C# および Visual Basic)」を参照してください。

反復子のメソッドは、アクセサーを取得し、

反復子の申告は、次の条件を満たす必要があります:

暗黙の変換は yield return ステートメントの式の型から反復子の戻り値の型にする必要があります。

次の特性を持つメソッドに yield return またはの yield break ステートメントを含めることはできません:

例外処理

yield returnステートメントは、try-catch ブロックでキャッチすることはできません。yield return ステートメントで try-finally ステートメントを try ブロックでキャッチできます。

の yield break ステートメントは、try ブロックと catch ブロックでなく、finally ブロックで使用できます。

反復子のメソッド (外) foreach の本体で例外をスローする場合、反復子のメソッドの finally ブロックが実行されます。

技術的な実装

次のコードは、反復子のメソッドから IEnumerable<string> を返し、要素間を繰り返します。

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

MyIteratorMethod の呼び出しは、メソッドの本体は実行されません。代わり elements の呼び出しは、変数に IEnumerable<string> を返します。

foreach のループ反復で、MoveNext のメソッドは elementsに対して呼び出されます。この呼び出しは yield return の次のステートメントに到達するまで MyIteratorMethod の本体を実行します。yield return ステートメントによって返される式はループ本体で使用するための element 変数の値 **IEnumerable<string>**の要素内で、のプロパティを Current だけでなく、決まりますが、

foreach のループの各反復で、反復子本体の実行は yield return ステートメントに到達するときに中断した場所からか続行され、もう一度停止します。foreach のループで反復子のメソッドまたは yield break ステートメントの最後に到達すると完了します。

使用例

次の例に for のループ内にある yield return ステートメントがあります。Process の foreach のステートメント本体の各反復で Power の反復子の関数への呼び出しを作成します。反復子の関数に対する各呼び出しは for のループの次の反復処理中に発生する yield return ステートメントの次の実装に移動します。

反復子のインターフェイス型の反復子メソッドの戻り値の型は IEnumerableです。反復子のメソッドが呼び出されると、数値の累乗を含む列挙可能なオブジェクトを返します。

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.IEnumerable 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
}

次の例は、反復子である get のアクセサーを示します。例では、の各 yield return ステートメントは、ユーザー定義のクラスのインスタンスを返します。

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# 言語仕様」を参照してください。言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。

参照

関連項目

foreach、in (C# リファレンス)

概念

C# プログラミング ガイド

その他の技術情報

C# リファレンス

反復子 (C# および Visual Basic)