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


当前回答

除了其他好的答案外,请注意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

其他回答

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。

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

举个例子:

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

收益率突破只是一种表示最后一次返回并且不返回任何值的方式

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

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

用一个例子来解释它的意思:

public IEnumerable<int> SampleNumbers() { Int counter = 0; 收益回报计数器; 计数器=计数器+ 2; 收益回报计数器; 计数器=计数器+ 3; 收益回报计数器; }

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

值得注意的是,本例中的counter变量是一个局部变量。在第二次迭代返回值2之后,第三次迭代从之前的位置开始,同时保留名为counter的局部变量之前的值2。

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

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