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 returnand的上下文关键字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 returnor中使用时yield break,它是一个关键字并创建一个迭代器。
在其他地方使用时,它是一个正常的标识符。

yield比普通的收藏品更有用;它也可以用来实现原始协程。

于 2011-11-25T20:21:16.850 回答