任何人都可以看到使用“break”或“return”无法实现的“yield break”语句的用法。
这句话似乎完全没用。更重要的是,如果没有这个陈述,“收益率返回X”语句可以简化为“收益率X”,这更加可读。
我错过了什么?
答案 0 :(得分:57)
要给出一个代码示例,假设您要编写一个迭代器,如果源为null或为空,则不返回任何内容。
public IEnumerable<T> EnumerateThroughNull<T>(IEnumerable<T> source)
{
if (source == null)
yield break;
foreach (T item in source)
yield return item;
}
如果没有yield break,就不可能在迭代器中返回一个空集。
答案 1 :(得分:9)
yield break指定该方法应该停止返回结果。 “返回”本身不够好,甚至可能导致错误,因为该方法的返回类型必须是IEnumerable。
我不确定为什么还需要return关键字。我最好的猜测是,它有助于使声明的意图更清晰一些。
如果您有兴趣,本文将解释幕后产量是什么
答案 2 :(得分:6)
for(int i = 0; i < 10; ++i) {
if(i > 5) { break; }
yield return i;
}
for(int v = 2710; v < 2714; v+=2) {
yield return v;
}
for(int s = 16; s < 147; ++s) {
if(s == 27) { yield break; }
else if(s > 17) { yield return s; }
}
输出将是这些值的IEnumerable:0,1,2,3,4,5,2710,2712,18,19,20,21,22,23,24,25,26
这里有一些没有用处的方法,但它说明你可以将yield break和break结合到同一个方法中,它们会做两件不同的事情! Break只是突破循环,yield break完全结束了该方法。
我想没有使用返回的原因是因为你没有在方法中自己返回IEnumerable。此外,对于这种反复的情况,难道你不认为收益率突破比回报更清晰吗?我亲自做。
答案 3 :(得分:3)
在迭代器块中使用return
语句是非法的。此外,break
语句可以在迭代器块中实现双重目的,如果允许它影响迭代:它可以用于突破循环或从开关中断开,并且可以使用它打破整个迭代。
yield return
和yield break
并且它们本身就是两个关键字,它们似乎都是必要的。
答案 4 :(得分:0)
您需要区分返回已存在的IEnumerable实现(可能是要返回List)和匿名迭代器。
您不能只使用return或break,因为这些是可用于其他目的的有效关键字。你也不能自己使用yield,因为你需要有一种方法来指定你是在枚举中返回一个项目,还是结束枚举,因此需要yield return和yield break。
答案 5 :(得分:0)
return
语句用于从函数返回值。
如果你有这样的迭代器函数:
public IEnumerable<int> IteratorOverInt() { }
上述函数中的return语句需要返回一个填充的IEnumerable<int>
。
public IEnumerable<int> IteratorOverInt() {
return new List<int> { 1, 2, 3, 4 };
}
但是如果您正在使用迭代器函数,那么您将使用yield return
,因此您的代码可能如下所示:
public IEnumerable<int> IteratorOverInt() {
for (int i = 0; i < 4; i++) {
yield return i;
}
}
所以yield return
返回int
,而方法签名要求IEnumerable<int>
return
声明在上述情况下会做什么?返回结果会超过收益率?连接到什么收益? return
在上述情况下没有多大意义。
因此,我们需要一种在迭代器块中有意义的return
方法,这就是yield break
的原因。
当然你可以用break
来做,但是如果你有更多的代码可以执行,你将如何退出函数体?将所有内容包装在复杂的if-else块中?我会说yield break
只会更好。