我什么时候应该使用收益率?什么时候才能使用回报?
答案 0 :(得分:22)
返回可枚举时使用yield,并且此时没有所有结果。
实际上,当我想迭代大量信息(数据库,平面文件等)时,我已经使用了yield,而且我不想先将所有内容加载到内存中。 Yield是一种很好的方法,可以在不加载所有内容的情况下迭代块。
答案 1 :(得分:7)
收益率是迭代器。
它允许你处理小燕子中的列表,这对大型列表很有用。
关于Yield的神奇之处在于它会记住你在调用之间的位置。
如果您没有迭代,则不需要收益。
答案 2 :(得分:7)
yield
关键字非常强大。它基本上允许您快速返回IEnumerable
和IEnumerator
个对象,而无需对其进行明确编码。
考虑一个您想要返回两个IEnumerable对象的交集的场景。以下是使用yield关键字的方法。
public static class Program
{
public static void Main()
{
IEnumerable<object> lhs = new List<int> { 1, 2, 3, 4, 5 };
IEnumerable<object> rhs = new List<int> { 3, 4, 5, 6, 7 };
foreach (object item in IntersectExample.Intersect(lhs, rhs))
{
Console.WriteLine(item);
break;
}
}
}
public static class IntersectExample
{
public static IEnumerable<object> Intersect(IEnumerable<object> lhs, IEnumerable<object> rhs)
{
var hashset = new HashSet<object>();
foreach (object item in lhs)
{
if (!hashset.Contains(item))
{
hashset.Add(item);
}
}
foreach (object item in rhs)
{
if (hashset.Contains(item))
{
yield return item;
}
}
}
}
在你完全意识到发生了什么之前,很难理解这一点。通常,当您将两个集相交时,您将完成整个操作,然后将结果返回给调用者。这意味着操作的运行时复杂性为O(m + n)
,其中m
和n
是要交叉的集合的大小,而不管您之后对结果执行的操作。但是,在我的例子中,我只是想从结果中挑选出第一个项目。使用IEnumerable
关键字创建的yield
可以非常轻松地延迟部分处理,直到实际需要为止。我的示例在O(m)
中运行。另一种方法是对IEnumerable
进行编码并手动维护其中的状态。 yield
关键字的强大之处在于它为您创建了状态机。
答案 3 :(得分:6)
yield
构造用于创建可以连续生成多个值的迭代器:
IEnumerable<int> three_numbers() {
yield return 1;
yield return 2;
yield return 3;
}
...
foreach (var i in three_numbers()) {
// i becomes 1, 2 and 3, in turn.
}
答案 4 :(得分:1)
Yield Return将从该点继续该方法。例如,您希望循环遍历数组或列表,并在此时返回每个元素以供调用者处理。所以你将使用收益率回报。如果你想返回所有内容然后完成,你不需要那样做
答案 5 :(得分:1)
这里解释:
C# Language Reference
yield (C# Reference)
调用的方法将返回每个值,以便调用者可以枚举它们。
这意味着当您想要迭代返回的每个可能结果时,您将需要使用 yield 。