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