yield (C# リファレンス)
ステートメントで yield のキーワードを使用すると、表示 get のメソッド、演算子、またはアクセサーが反復子であることを示します。コレクションに対するカスタムのイテレーションを実行するために反復子を使用します。次の例では yield のステートメントの 2 とおりの形式を次に示します。
yield return <expression>;
yield break;
解説
各要素を一つずつ返すために yield return ステートメントを使用します。
foreach のステートメントまたは LINQ クエリを使用して、反復子のメソッドを実装します。foreach ループの各反復で反復子のメソッドを呼び出します。yield return ステートメントが反復子のメソッドに到達すると、expression は戻り、コードの現在の位置は保持されます。実装はその位置から反復子関数が呼び出されると、に再起動されます。
イテレーションの末尾に yield break ステートメントを使用できます。
反復子の詳細については、「反復子 (C# および Visual Basic)」を参照してください。
反復子のメソッドは、アクセサーを取得し、
反復子の申告は、次の条件を満たす必要があります:
戻り値の型は IEnumerable、IEnumerable<T>、IEnumerator、または IEnumerator<T>である必要があります。
申告は ref または t3c3bfhx(v=vs.110).md のパラメーターを持つことはできません。
暗黙の変換は yield return ステートメントの式の型から反復子の戻り値の型にする必要があります。
次の特性を持つメソッドに yield return またはの yield break ステートメントを含めることはできません:
匿名メソッド。詳細については、「匿名メソッド (C# プログラミング ガイド)」を参照してください。
unsafe ブロックを含むメソッド。詳細については、「unsafe (C# リファレンス)」を参照してください。
例外処理
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# の構文と使用法に関する信頼性のある情報源です。