我在MSDN中看到过这种语法:yield break
但我不知道它是做什么的.有人知道吗?
它指定迭代器已经结束.您可以将其yield break
视为return
不返回值的语句.
例如,如果将函数定义为迭代器,则函数体可能如下所示:
for (int i = 0; i < 5; i++) { yield return i; } Console.Out.WriteLine("You will see me");
请注意,在循环完成所有循环后,最后一行将被执行,您将在控制台应用程序中看到该消息.
或者像这样yield break
:
int i = 0; while (true) { if (i < 5) { yield return i; } else { // note that i++ will not be executed after this yield break; } i++; } Console.Out.WriteLine("Won't see me");
在这种情况下,永远不会执行最后一个语句,因为我们提前离开了函数.
结束迭代器块(例如,IEnumerable中没有更多元素).
告诉迭代器它已到达终点.
举个例子:
public interface INode { IEnumerableGetChildren(); } public class NodeWithTenChildren : INode { private Node[] m_children = new Node[10]; public IEnumerable GetChildren() { for( int n = 0; n < 10; ++n ) { yield return m_children[ n ]; } } } public class NodeWithNoChildren : INode { public IEnumerable GetChildren() { yield break; } }
yield
基本上使一个IEnumerable
方法的行为类似于一个合作(而不是先发制人)调度的线程.
yield return
就像一个调用"schedule"或"sleep"函数的线程来放弃对CPU的控制.就像一个线程一样,该IEnumerable
方法在紧接着的时刻重新获得控制,所有局部变量具有与放弃控制之前相同的值.
yield break
就像一个线程到达其功能的终点并终止.
人们谈论的是"状态机",但状态机实际上都是"线程".线程具有一些状态(即局部变量的值),并且每次调度它都需要一些操作才能达到新状态.关键点yield
在于,与我们习惯使用的操作系统线程不同,使用它的代码会被及时冻结,直到手动提前或终止迭代.
在Jon Skeet的C#深度书中,这个免费的样本章节详细介绍了迭代器块的整个主题.
该yield break
语句导致枚举停止.实际上,yield break
完成枚举而不返回任何其他项.
考虑到迭代器方法实际上有两种方法可以停止迭代.在一种情况下,该方法的逻辑可以在返回所有项之后自然地退出该方法.这是一个例子:
IEnumerableFindPrimes(uint startAt, uint maxCount) { for (var i = 0UL; i < maxCount; i++) { startAt = NextPrime(startAt); yield return startAt; } Debug.WriteLine("All the primes were found."); }
在上面的例子中,迭代器方法一旦maxCount
找到质数就会自然停止执行.
该yield break
语句是迭代器停止枚举的另一种方式.这是一种早期打破枚举的方法.这是与上述相同的方法.这次,该方法对方法可以执行的时间量有限制.
IEnumerableFindPrimes(uint startAt, uint maxCount, int maxMinutes) { var sw = System.Diagnostics.Stopwatch.StartNew(); for (var i = 0UL; i < maxCount; i++) { startAt = NextPrime(startAt); yield return startAt; if (sw.Elapsed.TotalMinutes > maxMinutes) yield break; } Debug.WriteLine("All the primes were found."); }
注意来电yield break
.实际上,它很早就退出了枚举.
yield break
还要注意,它的工作方式不同于普通的break
.在上面的示例中,yield break
退出方法而不进行调用Debug.WriteLine(..)
.
这里http://www.alteridem.net/2007/08/22/the-yield-statement-in-c/就是很好的例子:
public static IEnumerableRange( int min, int max ) { while ( true ) { if ( min >= max ) { yield break; } yield return min++; } }
和解释,如果yield break
在方法中命中一个语句,该方法的执行将停止而不返回.有一些时间情况,当你不想给出任何结果时,你可以使用yield break.
yield yield只是最后一次回报的一种方式,不返回任何值
例如
// returns 1,2,3,4,5 IEnumerableCountToFive() { yield return 1; yield return 2; yield return 3; yield return 4; yield return 5; yield break; yield return 6; yield return 7; yield return 8; yield return 9; }