“产量突破”是什么意思? 在 C# 中做什么?

发布于 2024-07-07 10:14:09 字数 165 浏览 10 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

洋洋洒洒 2024-07-14 10:14:10

告诉迭代器它已到达末尾。

举个例子:

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

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;
    }
}
你怎么敢 2024-07-14 10:14:10

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

yield return 就像一个线程调用“schedule”或“sleep”函数来放弃对CPU的控制。 就像线程一样,IEnumerable 方法立即重新获得控制权,所有局部变量的值与放弃控制之前的值相同。

yield break 就像一个线程到达其函数末尾并终止。

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

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

yield return is 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 break is like a thread reaching the end of its function and terminating.

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 yield is 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.

醉殇 2024-07-14 10:14:10

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

,例如

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

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

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;
 }
奈何桥上唱咆哮 2024-07-14 10:14:10

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 退出该方法,而不调用 Debug.WriteLine(..)

The yield break statement causes the enumeration to stop. In effect, yield break completes the enumeration without returning any additional items.

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 maxCount primes have been found.

The yield break statement 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.

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.

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

清引 2024-07-14 10:14:10

这里 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++;
   }
}

和解释,如果在方法中命中 yield break 语句,则执行该方法停止而不返回。 在某些情况下,当您不想给出任何结果时,可以使用yield break。

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

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 break statement 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.

对你而言 2024-07-14 10:14:10

除了其他好的答案之外,请注意,在嵌套循环中,yield break 不像正常的 break 那样工作。 如果 break 只会停止当前循环,但不会停止任何外部循环,则 yield break 将停止整个枚举:

IEnumerable<int> Iterate() {
  for(int i=0; i<5; i++) {
    yield return i;

    for(int j=0; j<5; j++) {
      if ((i*10 + j) > 30)
        // This will stop the whole enumeration, even if there's
        // an outer "for" loop
        yield break;

      yield return (i*10 + j);
    }
  }
}

Console.WriteLine(string.Join(", ", Iterate().Select(i => i.ToString())));
// 0, 0, 1, 2, 3, 4, 1, 10, 11, 12, 13, 14, 2, 20, 21, 22, 23, 24, 3, 30

Apart from the other good answers, note that yield break does not work like a normal break when in comes to nested loops. Where a break would only stop the current loop but not any outer loop, yield break will stop the whole enumeration:

IEnumerable<int> Iterate() {
  for(int i=0; i<5; i++) {
    yield return i;

    for(int j=0; j<5; j++) {
      if ((i*10 + j) > 30)
        // This will stop the whole enumeration, even if there's
        // an outer "for" loop
        yield break;

      yield return (i*10 + j);
    }
  }
}

Console.WriteLine(string.Join(", ", Iterate().Select(i => i.ToString())));
// 0, 0, 1, 2, 3, 4, 1, 10, 11, 12, 13, 14, 2, 20, 21, 22, 23, 24, 3, 30
纵性 2024-07-14 10:14:10

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

用一个例子来解释一下含义:

 public IEnumerable;   样本编号() 
      { 
          整数计数器 = 0; 
          收益率计数器; 

          计数器 = 计数器 + 2; 

          收益率计数器; 

          计数器 = 计数器 + 3; 

          收益回报计数器; 
      } 
  

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

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

The yield keyword is used together with the return keyword to provide a value to the enumerator object. yield return specifies 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.

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

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

It’s important to note that counter variable 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 counter which was 2.

飘然心甜 2024-07-14 10:14:09

它指定迭代器已结束。 您可以将 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");

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

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

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:

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.

八巷 2024-07-14 10:14:09

结束迭代器块(例如,表示 IEnumerable 中不再有元素)。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文