可能是重复问题:
在C#中,“yield break;”有什么作用?
有人能看到“yield break”语句的用途,而这不能通过使用“break”或“return”来实现。
这个语句似乎完全没有用处。更重要的是,如果没有这个语句,“yield return X”语句可以简化为“yield X”,这样更易读。
我错过了什么吗?
可能是重复问题:
在C#中,“yield break;”有什么作用?
有人能看到“yield break”语句的用途,而这不能通过使用“break”或“return”来实现。
这个语句似乎完全没有用处。更重要的是,如果没有这个语句,“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指定方法应停止返回结果。仅使用"return"是不够的,甚至可能导致错误,因为方法的返回类型必须是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; }
}
return
语句是非法的。此外,如果允许break
语句影响迭代过程,则break
语句可以在迭代器块中发挥双重作用:它可用于跳出循环或跳出开关,并可用于跳出整个迭代。
yield return
和yield break
是两个独立的关键字,它们似乎都是必要的。你需要区分返回已存在的IEnumerable实现(例如,你将要返回一个List)和匿名迭代器。
你不能仅仅使用return或break,因为它们是可以用于其他目的的有效关键字。你也不能仅仅使用yield,因为你需要有一种方式来指定你是否正在返回枚举中的项目,或者结束枚举,因此需要使用yield return和yield break。
return
语句用于从函数中返回一个值。
如果您有一个像这样的迭代器函数:
public IEnumerable<int> IteratorOverInt() { }
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
语句会做什么?覆盖yield的结果?将任何内容连接到yield中?在上述情况下,return
没有太多意义。
因此,我们需要一种在迭代器块中有意义的return
方式,这就是为什么有yield break
的原因。
当然,您可以使用break
来实现,但是如果您有更多要执行的代码,那么如何退出函数体呢?将所有内容包装在复杂的if-else块中?我认为只使用yield break
会更好。
return new T[0]
相同,但不会创建空数组。 - user1228