web-dev-qa-db-ja.com

イールドブレイクの用途は何ですか?

重複の可能性:
C#で「yieldbreak;」は何をしますか?

「break」または「return」を使用することによって他の方法では達成できなかった「yieldbreak」ステートメントの使用法を誰かが見ることができますか。

この声明はまったく役に立たないようです。さらに、このステートメントがなければ、「yield return X」ステートメントは、はるかに読みやすい「yieldX」に簡略化できたはずです。

何が足りないのですか?

31
Miles Davis

コード例を示すために、ソースがnullまたは空の場合に何も返さないイテレーターを作成するとします。

public IEnumerable<T> EnumerateThroughNull<T>(IEnumerable<T> source)
{
    if (source == null)
        yield break;

    foreach (T item in source)
        yield return item;
}

イールドブレークがないと、イテレータ内に空のセットを返すことができなくなります。

63

yield breakは、メソッドが結果の戻りを停止する必要があることを指定します。メソッドの戻り値の型はIEnumerableである必要があるため、「return」だけでは十分ではないか、バグにつながる可能性さえあります。

Returnキーワードも必要な理由がわかりません。私の最善の推測は、それがステートメントの意図をもう少し明確にするのに役立つということです。

興味があれば、この記事では、yieldが舞台裏で何をしているのかを説明します

C#yieldキーワードの舞台裏

9
Bob

イールドブレイクとブレイクは完全に異なることをします!見て

for(int i = 0; i < 10; ++i) {
   if(i > 5) { break; }
   yield return i;
}

for(int v = 2710; v < 2714; v+=2) {
   yield return v;
}

for(int s = 16; s < 147; ++s) {
   if(s == 27) { yield break; }
   else if(s > 17) { yield return s; }
}

出力は、次の値のIEnumerableになります:0、1、2、3、4、5、2710、2712、18、19、20、21、22、23、24、25、26

これは何の役にも立たないいくつかの方法ですが、yield breakとbreakを同じ方法に組み合わせることができ、2つの異なることを行うことを示しています。 Breakはループから抜け出すだけで、yieldbreakはメソッドを完全に終了します。

Returnが使用されない理由は、メソッドで自分でIEnumerableを返さないためだと思います。その上、このような反復的な状況では、利回りのブレークはリターンよりも明確だと思いませんか?私は個人的にします。

6
Ray Hidayat

イテレータブロックでreturnステートメントを使用することは違法です。さらに、breakステートメントは、反復に影響を与えることが許可されている場合、イテレーターブロック内で二重の目的を果たすことができます。ループまたはスイッチから抜け出すために使用できます。反復全体から抜け出すために使用されます。

yield returnおよびyield breakとはそれ自体が2つのキーワードであり、どちらも必要なようです。

3
yfeldblum

すでに存在するIEnumerable実装を返すこと(おそらくリストを返すことになる)と匿名イテレーターを区別する必要があります。

Returnまたはbreakは、他の目的に使用できる有効なキーワードであるため、単に使用することはできません。また、列挙内のアイテムを返すのか、列挙を終了するのかを指定する方法が必要なため、yieldを単独で使用することはできません。したがって、yieldreturnとyieldbreakが必要です。

0
casperOne

returnステートメントは、関数から値を返すために使用されます。

このようなイテレータ関数がある場合:

public IEnumerable<int> IteratorOverInt() { }

上記の関数のreturnステートメントは、入力されたIEnumerable<int>を返す必要があります。

public IEnumerable<int> IteratorOverInt() {
    return new List<int> { 1, 2, 3, 4 };
}

ただし、イテレータ関数で作業している場合は、yield returnを使用するため、コードは次のようになります。

public IEnumerable<int> IteratorOverInt() {
    for (int i = 0; i < 4; i++) {
        yield return i;
    }
}

したがって、yield returnintを返しますが、メソッドシグネチャはIEnumerable<int>を要求します

上記の場合、returnステートメントは何をしますか?利回りを上書きする結果を返しますか?何でも歩留まりに連結しますか?上記の場合、returnはあまり意味がありません。

したがって、イテレータブロックで意味のあるreturnへの方法が必要です。そのため、yield breakがあります。

もちろん、breakでそれを行うことができますが、実行するコードがさらにある場合、関数本体をどのように終了しますか?複雑なif-elseブロックですべてをラップしますか? yield breakがあるだけの方がいいと思います。

0
chakrit