■C#のyield
C#のyieldは、コレクションのデータを一つずつ返す場合に使います。
yieldは yield return または yield break の2つがあります。yield returnは、コレクションのデータを一つずつ返却する場合に使って、yield breakは、返却を止めてIterationループを中止する場合に使います。
static IEnumerable
GetCity()
{
yield return “tokyo”; // 1回目の返却値
yield return “kyoto”; // 2回目の返却値
yield return “osaka”; // 3回目の返却値
}
static void Main(string[] args)
{
foreach (string s in GetCity())
{
Console.WriteLine(s);
}
}
こういう返却方式は下記のようなシーンで使えます。
・データの量が多くて、一気に返却をするより、少しずつ返却した方が効率的な場合
・ある関数が無制限のデータを返却する場合
・すべてのデータを一気に計算すると処理が重くなるので、計算する度にOn Demandで処理した方が良い場合
■C#のyieldとEnumerator
C#でyieldがよく使われる時は、集合的なデータを持つコレクションクラスです。一般的にコレクションクラスはデータの要素を使うために Enumerator(Iterator) を作ることが多く、このEnumeratorはyieldを利用して作ることができます。
コレクションタイプまたは、EnumerableクラスでGetEnumerator()を作成する方法としてyieldを使うことができます。GetEnumerator()関数内でyield returnを利用して渡す処理を作って、IEnumeratorインターフェースを返却することができます。
下記のサンプルを参考に理解してみましょう。
public class cityList
{
private string[] cities = { “tokyo”, “osaka”, “yokohama”, “nagoya”, “nagano” };
public IEnumerator GetEnumerator()
{
int i = 0;
while (i < cities.Length)
{
yield return cities[i];
i++;
}
}
…
}
■C#のyieldの処理順番
yieldを持ってるIteration関数を呼び出すと以下の順で実行されます。
呼び出し元(X)がIEnumerableを返却する関数(Y)を呼び出すと、yield return文で一つの値を返却し、該当の関数(Y)の場所を記憶しておきます。呼び出し元(X)がループをもう一度して関数(Y)を呼び出すと、メソッドが記憶された次の行から実行され、yield returnで次の値を返却します。