什么是“屈服中断;”用C#做吗?

问题描述 投票:493回答:10

我已经在MSDN中看到此语法:yield break,但我不知道它的作用。有人知道吗?

c# .net yield
10个回答
529
投票

它指定迭代器已结束。您可以将yield break视为不返回值的yield break语句。

例如,如果将函数定义为迭代器,则函数的主体可能看起来像这样:

return

请注意,循环完成所有循环后,将执行最后一行,您将在控制台应用程序中看到该消息。

或类似for (int i = 0; i < 5; i++) { yield return i; } Console.Out.WriteLine("You will see me");

yield break

在这种情况下,因为我们提早离开了函数,所以永远不会执行最后一条语句。


57
投票

结束迭代器块(例如,说IEnumerable中没有更多元素了。)


29
投票

告诉迭代器结束了。

例如:

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");

21
投票

[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>就像一个线程调用“计划”或“睡眠”函数以放弃对CPU的控制。就像线程一样,yield return方法随后立即重新获得控制,所有局部变量的值与放弃控制之前的值相同。

[IEnumerable<T>就像一个线程到达其函数的结尾并终止。

人们谈论“状态机”,但是状态机实际上是所有“线程”。线程具有某种状态(即局部变量的值),并且每次对其进行调度时,它都会采取一些操作以达到新的状态。 yield break的关键点在于,与我们习惯的操作系统线程不同,使用它的代码会及时冻结,直到手动推进或终止迭代为止。


13
投票

[Jon Skeet的书yieldfree sample chapter中很好地涵盖了迭代器块的整个主题。


9
投票

C# in Depth语句使枚举停止。实际上,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."); } 素数,则迭代器方法自然会停止执行。

maxCount语句是迭代器停止枚举的另一种方法。这是尽早突破枚举的一种方法。这是与上述相同的方法。这次,该方法对方法可以执行的时间有限制。

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


7
投票

Debug.WriteLine(..)是很好的例子:

公共静态IEnumerable  Range(int min,int max){   而(true)   {      如果(min> = max)      {         产量中断;      }      收益回报率最低++;   }}

并且说明,如果在方法中命中http://www.alteridem.net/2007/08/22/the-yield-statement-in-c/语句,则该方法的执行将停止且不会返回。在某些情况下,当您不想给出任何结果时,可以使用yield break。


5
投票

屈服中断只是最后一次回报的一种方式,不返回任何值

例如

yield break

4
投票

如果您的意思是“实际收益率是多少,那么它是如何工作的”-有关详细信息,请参见Raymond Chen的博客// returns 1,2,3,4,5 IEnumerable<int> CountToFive() { 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; }

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


-2
投票

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

使用示例解释含义:

https://devblogs.microsoft.com/oldnewthing/20080812-00/?p=21273

迭代时返回的值是:0、2、5。

重要的是,在此示例中,counter变量是局部变量。在第二次迭代返回值2之后,第三次迭代从其之前的位置开始,同时保留了先前的值名为counter的局部变量为2。

© www.soinside.com 2019 - 2024. All rights reserved.