任何人都可以看到使用“break”或“return”无法实现的“yield break”语句的用途。
这种说法似乎完全没有用。更重要的是,如果没有这个语句,“yield return X”语句可能会被简化为“yield X”,这样更易读。
我错过了什么?
任何人都可以看到使用“break”或“return”无法实现的“yield break”语句的用途。
这种说法似乎完全没有用。更重要的是,如果没有这个语句,“yield return X”语句可能会被简化为“yield X”,这样更易读。
我错过了什么?
举一个代码示例,假设您要编写一个迭代器,如果源为 null 或为空,则该迭代器不返回任何内容。
public IEnumerable<T> EnumerateThroughNull<T>(IEnumerable<T> source)
{
if (source == null)
yield break;
foreach (T item in source)
yield return item;
}
如果没有 yield break,就不可能在迭代器中返回一个空集。
yield break 指定方法应该停止返回结果。“返回”本身不够好,甚至可能导致错误,因为方法的返回类型必须是 IEnumerable。
我不确定为什么还需要 return 关键字。我最好的猜测是它有助于使声明的意图更加清晰。
如果你有兴趣,这篇文章解释了 yield 在幕后做了什么
yield break 和 break 做完全不同的事情!看
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 完全结束方法。
我猜未使用 return 的原因是因为您没有在方法中自己返回 IEnumerable 。此外,对于这种迭代情况,您不认为 yield break 比 return 更清晰吗?我个人会。
return
在迭代器块中使用语句是非法的。此外,break
如果允许该语句影响迭代,则该语句可以在迭代器块中用于双重目的:它可以用于跳出循环或跳出开关,并且可以用于跳出整个迭代。
yield return
and yield break
and 本身就是两个关键字,它们似乎都是必要的。
您需要区分返回一个已经存在的 IEnumerable 实现(也许您将返回一个 List)和一个匿名迭代器。
您不能只使用 return 或 break,因为它们是可用于其他目的的有效关键字。您也不能单独使用yield,因为您需要有一种方法来指定是返回枚举中的项目还是结束枚举,因此需要yield return 和yield break。
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
.
当然你可以用 a 来做break
,但是如果你有更多要执行的代码,你将如何退出函数体?将所有内容包装在一个复杂的 if-else 块中?我会说只是拥有yield break
会更好。