“yield关键字”在迭代器块之外是否有用?

时间:2011-11-25 20:19:28

标签: c# .net yield-keyword

yield关键字文档说:

  

yield关键字向编译器发出信号通知它所在的方法   出现是一个迭代器块。

我在任何迭代器块之外使用yield关键字遇到过代码。这应该被视为编程错误还是只是罚款?

编辑抱歉忘记发布我的代码:

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

感谢。

3 个答案:

答案 0 :(得分:22)

在迭代器块之外使用yield好的 - 这只是意味着它没有被用作上下文关键字

例如:

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

此时它是一个上下文关键字(它的从不是一个“完整”关键字),它只是一个标识符。除非它明确地是正常清晰度的最佳选择,否则无论如何我都会尽量避免使用它,但有时可能会这样。

您只能将它用作yield returnyield break的上下文关键字,它们只在迭代器块中有效。 (它们是将转换为迭代器的方法。)

编辑:回答你的“应该允许”这个问题......是的,它应该。否则,在发布C#2时,使用yield作为标识符的所有现有C#1代码都将变为无效。它应该小心使用,并且C#团队已经确保它实际上从不模糊,但它有效是有意义的。

对于许多其他上下文关键字也是如此 - “来自”,“选择”,“在哪里”等。您是否希望阻止这些关键字成为标识符?

答案 1 :(得分:11)

这就是说,如果在方法中使用yield,该方法将成为迭代器块。

此外,由于yieldcontextual keyword,因此可以在其他地方自由使用,而完整关键字则无法使用(例如变量名称)。

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;
}

另请参阅:此答案显示使用一个接一个的收益率。 Clever Uses of Iterator Blocks

答案 2 :(得分:5)

yield上下文关键字yield returnyield break中使用时,它是一个关键字并创建一个迭代器 在其他地方使用时,它是一个普通的标识符。

yieldmore than ordinary collections非常有用;它也可以用来实现原始协同程序。