什么是“收益中断”,在C#中做?

我在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 { IEnumerable<Node> GetChildren(); } public class NodeWithTenChildren : INode { private Node[] m_children = new Node[10]; public IEnumerable<Node> GetChildren() { for( int n = 0; n < 10; ++n ) { yield return m_children[ n ]; } } } public class NodeWithNoChildren : INode { public IEnumerable<Node> GetChildren() { yield break; } } 

yield基本上使一个IEnumerable<T>方法的行为类似于合作(而不是预先)预定的线程。

yield return就像是调用“时间表”或“睡眠”函数来放弃对CPU的控制。 就像一个线程, IEnumerable<T>方法立即重新获得控制权,所有局部variables具有与控制权被放弃之前相同的值。

yield break就像是一个到达其function和终止的线程。

人们谈论的是一个“状态机”,但是一个状态机确实是一个“线程”。 一个线程有一些状态(即局部variables的Ie值),并且每次调度它都会采取一些行动来达到一个新的状态。 关于yield的关键点是,与我们习惯的操作系统线程不同,使用它的代码会被冻结,直到迭代被手动提前或终止。

Jon Skeet的书C#深入这个免费样本章节中 ,覆盖了迭代器块的整个主题。

这里http://www.alteridem.net/2007/08/22/the-yield-statement-in-c/是非常好的例子:;

公共静态IEnumerable <int>范围(int min,int max)
 {
   而(真)
    {
      如果(min> = max)
       {
         产量突破
       }
      产量回报最小值++;
    }
 }

并解释,如果一个方法内部命中一个yield break语句,该方法的执行就会停止而不返回。 有一些时间情况,当你不想给出任何结果,那么你可以使用收益率突破。

如果你的意思是“什么是真正的收益中断”,那么“它是如何工作的” – 详见Raymond Chen的博客http://blogs.msdn.com/oldnewthing/archive/2008/08/12/8849519。; ASPX

C#迭代器生成一些非常复杂的代码。

yield break语句导致枚举停止。 实际上, yield break完成枚举而不返回任何附加项目。

考虑一下迭代器方法实际上有两种方法可以停止迭代。 在一种情况下,该方法的逻辑可以在返回所有项目后自然退出该方法。 这里是一个例子:

 IEnumerable<uint> FindPrimes(uint startAt, uint maxCount) { for (var i = 0UL; i < maxCount; i++) { startAt = NextPrime(startAt); yield return startAt; } Debug.WriteLine("All the primes were found."); } 

在上面的例子中,一旦findmaxCount素数,迭代器方法自然会停止执行。

yield break语句是迭代器停止枚举的另一种方法。 这是一个早点摆脱枚举的方法。 这里是与上面相同的方法。 这一次,该方法对该方法可以执行的时间量有限制。

 IEnumerable<uint> FindPrimes(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(..)情况下退出该方法。

yield关键字与return关键字一起使用,为枚举器对象提供一个值。 yield return指定返回的值或值。 当yield yield return语句到达时,当前位置被存储。 下一次调用迭代器时,将从此位置重新启动执行。

用一个例子来解释含义:

  public IEnumerable<int> SampleNumbers() { int counter = 0; yield return counter; counter = counter + 2; yield return counter; counter = counter + 3; yield return counter ; } 

迭代时返回的值为:0,2,5。

注意在这个例子中计数器variables是一个局部variables是很重要的。 在第二次迭代返回值2之后,第三次迭代从之前离开的位置开始,同时保留名为counter的局部variables为2的前一个值。