yield
关键字文档说:
yield关键字向编译器发出信号通知它所在的方法 出现是一个迭代器块。
我在任何迭代器块之外使用yield
关键字遇到过代码。这应该被视为编程错误还是只是罚款?
编辑抱歉忘记发布我的代码:
int yield = previousVal/actualVal;
return yield; // Should this be allowed!!!???
感谢。
答案 0 :(得分:22)
在迭代器块之外使用yield
是好的 - 这只是意味着它没有被用作上下文关键字。
例如:
// No idea whether this is financially correct, but imagine it is :)
decimal yield = amountReturned / amountInvested;
此时它不是一个上下文关键字(它的从不是一个“完整”关键字),它只是一个标识符。除非它明确地是正常清晰度的最佳选择,否则无论如何我都会尽量避免使用它,但有时可能会这样。
您只能将它用作yield return
和yield break
的上下文关键字,它们只在迭代器块中有效。 (它们是将转换为迭代器的方法。)
编辑:回答你的“应该允许”这个问题......是的,它应该。否则,在发布C#2时,使用yield
作为标识符的所有现有C#1代码都将变为无效。它应该小心使用,并且C#团队已经确保它实际上从不模糊,但它有效是有意义的。
对于许多其他上下文关键字也是如此 - “来自”,“选择”,“在哪里”等。您是否希望阻止这些关键字成为标识符?
答案 1 :(得分:11)
这就是说,如果在方法中使用yield
,该方法将成为迭代器块。
此外,由于yield
是contextual 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 return
或yield break
中使用时,它是一个关键字并创建一个迭代器
在其他地方使用时,它是一个普通的标识符。
yield
对more than ordinary collections非常有用;它也可以用来实现原始协同程序。