MSDN: でこの構文を見たことがありますyield break
が、それが何をするのかわかりません。誰か知っていますか?
8 に答える
イテレータが終了したことを指定します。値を返さないステートメントyield break
と考えることができます。return
たとえば、関数を反復子として定義すると、関数の本体は次のようになります。
for (int i = 0; i < 5; i++)
{
yield return i;
}
Console.Out.WriteLine("You will see me");
ループがすべてのサイクルを完了すると、最後の行が実行され、コンソール アプリにメッセージが表示されることに注意してください。
または次のようにyield break
:
int i = 0;
while (true)
{
if (i < 5)
{
yield return i;
}
else
{
// note that i++ will not be executed after this
yield break;
}
i++;
}
Console.Out.WriteLine("Won't see me");
この場合、関数を早期に終了したため、最後のステートメントは実行されません。
イテレータ ブロックを終了します (たとえば、IEnumerable にこれ以上要素がないことを示します)。
最後に達したことを反復子に伝えます。
例として:
public interface INode
{
IEnumerable<Node> GetChildren();
}
public class NodeWithTenChildren : INode
{
private Node[] m_children = new Node[10];
public IEnumerable<Node> GetChildren()
{
for( int n = 0; n < 10; ++n )
{
yield return m_children[ n ];
}
}
}
public class NodeWithNoChildren : INode
{
public IEnumerable<Node> GetChildren()
{
yield break;
}
}
このyield break
ステートメントにより、列挙が停止します。実際には、yield break
追加の項目を返さずに列挙を完了します。
反復子メソッドが反復を停止する方法が実際には 2 つあると考えてください。場合によっては、メソッドのロジックは、すべての項目を返した後にメソッドを自然に終了できます。次に例を示します。
IEnumerable<uint> FindPrimes(uint startAt, uint maxCount)
{
for (var i = 0UL; i < maxCount; i++)
{
startAt = NextPrime(startAt);
yield return startAt;
}
Debug.WriteLine("All the primes were found.");
}
maxCount
上記の例では、素数が見つかると iterator メソッドは自然に実行を停止します。
yield break
ステートメントは、反復子が列挙を停止する別の方法です。列挙から早期に抜け出す方法です。こちらも上記と同じ方法です。今回は、メソッドの実行時間に制限があります。
IEnumerable<uint> FindPrimes(uint startAt, uint maxCount, int maxMinutes)
{
var sw = System.Diagnostics.Stopwatch.StartNew();
for (var i = 0UL; i < maxCount; i++)
{
startAt = NextPrime(startAt);
yield return startAt;
if (sw.Elapsed.TotalMinutes > maxMinutes)
yield break;
}
Debug.WriteLine("All the primes were found.");
}
への呼び出しに注意してくださいyield break
。実際には、列挙を早期に終了しています。
yield break
は単なるプレーンとは異なる動作をすることにも注意してくださいbreak
。上記の例でyield break
は、 を呼び出さずにメソッドを終了しますDebug.WriteLine(..)
。
ここhttp://www.alteridem.net/2007/08/22/the-yield-statement-in-c/は非常に良い例です:
public static IEnumerable<int> Range( int min, int max ) { while (真) { もし (最小 >= 最大) { 利回りブレーク; } 利回りリターン分++; } }
また、yield break
ステートメントがメソッド内でヒットした場合、そのメソッドの実行はリターンなしで停止するという説明。結果を出したくない場合は、yield break を使用できます。
yield キーワードを return キーワードと一緒に使用して、列挙子オブジェクトに値を提供します。yield returnは、返される値を指定します。yield return ステートメントに到達すると、現在の場所が格納されます。次に反復子が呼び出されたときに、この場所から実行が再開されます。
例を使用して意味を説明するには:
public IEnumerable<int> SampleNumbers() { int counter = 0; yield return counter; counter = counter + 2; yield return counter; counter = counter + 3; yield return counter ; }
これを繰り返したときに返される値は、0、2、5 です。
この例のカウンター変数はローカル変数であることに注意してください。2 の値を返す 2 番目の反復の後、2だったcounterという名前のローカル変数の前の値を保持しながら、3 番目の反復は前に終了した場所から開始します。