"yield break" 是什么意思?在 C# 中做什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/231893/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 19:08:38  来源:igfitidea点击:

What does "yield break;" do in C#?

c#.netyield

提问by skb

I have seen this syntax in MSDN: yield break, but I don't know what it does. Does anyone know?

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

采纳答案by Damir Zeki?

It specifies that an iterator has come to an end. You can think of yield breakas a returnstatement which does not return a value.

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

For example, if you define a function as an iterator, the body of the function may look like this:

例如,如果您将函数定义为迭代器,则函数体可能如下所示:

for (int i = 0; i < 5; i++)
{
    yield return i;
}

Console.Out.WriteLine("You will see me");

Note that after the loop has completed all its cycles, the last line gets executed and you will see the message in your console app.

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

Or like this with yield break:

或者像这样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");

In this case the last statement is never executed because we left the function early.

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

回答by Brian

Ends an iterator block (e.g. says there are no more elements in the IEnumerable).

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

回答by Tony Lee

If what you mean by "what does yield break really do", is "how does it work" - See Raymond Chen's blog for details http://blogs.msdn.com/oldnewthing/archive/2008/08/12/8849519.aspx

如果您所说的“yield break 的真正作用是什么”,是“它是如何工作的” - 有关详细信息,请参阅 Raymond Chen 的博客http://blogs.msdn.com/oldnewthing/archive/2008/08/12/8849519。 aspx

C# iterators generate some very complicated code.

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

回答by Trap

Tells the iterator that it's reached the end.

告诉迭代器它已经到达终点。

As an example:

举个例子:

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;
    }
}

回答by Marc Gravell

The whole subject of iterator blocks is covered well in this free sample chapterfrom Jon Skeet's book C# in Depth.

Jon Skeet 的C# in Depth一书中的这个免费示例章节很好地涵盖了迭代器块的整个主题。

回答by Marc Gravell

yieldbasically makes an IEnumerable<T>method behave similarly to a cooperatively (as opposed to preemptively) scheduled thread.

yield基本上使IEnumerable<T>方法的行为类似于协作(而不是抢占式)调度线程。

yield returnis like a thread calling a "schedule" or "sleep" function to give up control of the CPU. Just like a thread, the IEnumerable<T>method regains controls at the point immediately afterward, with all local variables having the same values as they had before control was given up.

yield return就像一个线程调用“调度”或“睡眠”函数来放弃对 CPU 的控制。就像线程一样,该IEnumerable<T>方法在之后立即重新获得控制权,所有局部变量都具有与放弃控制权之前相同的值。

yield breakis like a thread reaching the end of its function and terminating.

yield break就像一个线程到达其功能的末尾并终止。

People talk about a "state machine", but a state machine is all a "thread" really is. A thread has some state (I.e. values of local variables), and each time it is scheduled it takes some action(s) in order to reach a new state. The key point about yieldis that, unlike the operating system threads we're used to, the code that uses it is frozen in time until the iteration is manually advanced or terminated.

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

回答by Marc Gravell

Here http://www.alteridem.net/2007/08/22/the-yield-statement-in-c/is very good example:

这里http://www.alteridem.net/2007/08/22/the-yield-statement-in-c/是一个很好的例子:

public static IEnumerable<int> Range( int min, int max )
{
   while ( true )
   {
      if ( min >= max )
      {
         yield break;
      }
      yield return min++;
   }
}

and explanation, that if a yield breakstatement is hit within a method, execution of that method stops with no return. There are some time situations, when you don't want to give any result, then you can use yield break.

和解释,如果一个yield break语句在一个方法中被命中,该方法的执行将停止并且没有返回。在某些情况下,当您不想给出任何结果时,您可以使用 yield break。

回答by Eranga Dissanayaka

The yield keyword is used together with the return keyword to provide a value to the enumerator object. yield returnspecifies the value, or values, returned. When the yield return statement is reached, the current location is stored. Execution is restarted from this location the next time the iterator is called.

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

To explain the meaning using an example:

举例说明意思:

    public IEnumerable<int> SampleNumbers()
    {
        int counter = 0;
        yield return counter;

        counter = counter + 2;

        yield return counter;

        counter = counter + 3;

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

        counter = counter + 2;

        yield return counter;

        counter = counter + 3;

        yield return counter ;
    }

Values returned when this is iterated are: 0, 2, 5.

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

It's important to note that countervariable in this example is a local variable.After the second iteration which returns the value of 2, third iteration starts from where it left before, while preserving the previous value of local variable named counterwhich was 2.

需要注意的是,这个例子中的counter变量是一个局部变量。在返回值 2 的第二次迭代之后,第三次迭代从它之前离开的地方开始,同时保留名为counter的局部变量的先前值2。

回答by Wallace Kelly

The yield breakstatement causes the enumeration to stop. In effect, yield breakcompletes the enumeration without returning any additional items.

yield break语句导致枚举停止。实际上,yield break在不返回任何附加项的情况下完成枚举。

Consider that there are actually two ways that an iterator method could stop iterating. In one case, the logic of the method could naturally exit the method after returning all the items. Here is an example:

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

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

In the above example, the iterator method will naturally stop executing once maxCountprimes have been found.

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

The yield breakstatement is another way for the iterator to cease enumerating. It is a way to break out of the enumeration early. Here is the same method as above. This time, the method has a limit on the amount of time that the method can execute.

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

Notice the call to yield break. In effect, it is exiting the enumeration early.

注意对 的调用yield break。实际上,它提前退出了枚举。

Notice too that the yield breakworks differently than just a plain break. In the above example, yield breakexits the method without making the call to Debug.WriteLine(..).

yield break还要注意,它的工作方式与普通的break. 在上面的示例中,yield break退出方法而不调用Debug.WriteLine(..)

回答by John ClearZ

yield break is just a way of saying return for the last time and don't return any value

yield break 只是最后一次返回的一种方式,不返回任何值

e.g

例如

// 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;
 }