9

yieldキーワードのドキュメントには次のように書かれています。

yieldキーワードは、それが表示されるメソッドがイテレーターブロックであることをコンパイラーに通知します。

yieldイテレータブロックの外側でキーワードを使用しているコードに遭遇しました。これはプログラミングの間違いと見なす必要がありますか、それとも問題ありませんか?

編集申し訳ありませんが私のコードを投稿するのを忘れました:

int yield = previousVal/actualVal;
return yield; // Should this be allowed!!!???

ありがとう。

4

3 に答える 3

22

イテレータブロックのyield外部で使用しても問題ありません。これは、コンテキストキーワードとして使用されていないことを意味します

例えば:

// No idea whether this is financially correct, but imagine it is :)
decimal yield = amountReturned / amountInvested;

その時点で、コンテキストキーワードではなく(「完全な」キーワードになることはありません)、単なる識別子です。通常の明快さの観点から明らかに最良の選択でない限り、とにかくそれを使用しないようにしますが、時々そうなるかもしれません。

yield returnとのコンテキストキーワードとしてのみ使用できますyield break。これは、イテレータブロックでのみ有効です。(これらは、メソッドイテレーターに変えるものです。)

編集:あなたの「これは許されるべきか」という質問に答えるために...はい、そうすべきです。yieldそうしないと、C#2がリリースされたときに、識別子として使用されていた既存のC#1コードがすべて無効になってしまいます。注意して使用する必要があります。C#チームは、実際にはあいまいにならないようにしていますが、有効であることは理にかなっています。

「from」、「select」、「where」など、他の多くのコンテキストキーワードについても同じことが言えます。これらが識別子にならないようにしますか?

于 2011-11-25T20:22:23.307 に答える
11

つまりyield、メソッドで使用すると、そのメソッドはイテレータブロックになります。

また、yieldコンテキストキーワードと同様に、完全なキーワードでは使用できない他の場所(変数名など)でも自由に使用できます。

void AnotherMethod()
{
    foreach(var NotRandomNumber in GetNotVeryRandomNumbers())
    {
        Console.WriteLine("This is not random! {0}", NotRandomNumber);
    }
}

IEnumerable<int> GetNotVeryRandomNumbers()
{
    yield return 1;
    yield return 53;
    yield return 79;
    yield return 1;
    yield return 789;
}

// Perhaps more useful function below: (untested but you get the idea)
IEnumerable<Node> DepthFirstIteration(Node)
{
    foreach(var Child in Node.Children)
    {
        foreach(var FurtherChildren in DepthFirstIteration(Child))
        {
            yield return FurtherChildren;
        }
    }
    yield return Node;
}

参照:この回答は、次々に歩留まりを使用することを示しています。イテレータブロックの巧妙な使用

于 2011-11-25T20:21:25.197 に答える
5

yieldコンテキストキーワードです。またはで
使用すると、キーワードであり、イテレータを作成します。 他の場所で使用される場合、これは通常の識別子です。yield returnyield break

yield通常のコレクションよりも非常に便利です。また、プリミティブコルーチンを実装するために使用することもできます。

于 2011-11-25T20:21:16.850 に答える