34

重複の可能性:
「利回りが壊れる」とは何ですか?C#で行う?

「ブレーク」または「リターン」を使用することによって他の方法では達成できなかった「利回りブレーク」ステートメントの使用法を誰でも見ることができますか。

この発言はどう見ても無理がある。さらに、このステートメントがなければ、"yield return X" ステートメントは "yield X" に単純化でき、はるかに読みやすくなります。

私は何が欠けていますか?

4

6 に答える 6

68

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

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

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

yield break がないと、イテレータ内で空のセットを返すことができなくなります。

于 2009-01-31T01:04:38.080 に答える
9

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

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

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

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

于 2009-01-31T00:29:57.807 に答える
7

yield break と break はまったく別のことをします! 見て

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 はループから抜け出すだけで、yield break はメソッドを完全に終了します。

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

于 2009-01-31T01:04:40.483 に答える
3

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

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

于 2009-01-31T00:56:08.347 に答える
0

既に存在する IEnumerable 実装を返すこと (おそらく List を返すことになる) と匿名反復子を区別する必要があります。

これらは他の目的に使用できる有効なキーワードであるため、return や break だけを使用することはできません。また、列挙内のアイテムを返すか、列挙を終了するかを指定する方法が必要なため、yield を単独で使用することはできません。そのため、yield return と yield break が必要になります。

于 2009-01-31T00:52:18.807 に答える
0

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

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

public IEnumerable<int> IteratorOverInt() { }

上記の関数の return ステートメントは、filled を返す必要があり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 returnする while を返しますintIEnumerable<int>

return上記の場合、ステートメントは何をしますか? 利回りをオーバーライドして結果を返しますか? 利回りに何かを連結しますか? return上記の場合はあまり意味がありません。

したがってreturn、反復子ブロックで意味のある方法が必要ですyield break

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

于 2009-01-31T00:58:22.943 に答える