当前位置:  开发笔记 > 编程语言 > 正文

什么是"收益率突破"; 做C#?

如何解决《什么是"收益率突破";做C#?》经验,为你挑选了8个好方法。

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



1> Damir Zekić..:

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

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


@orad在这种情况下一个简单的`break`将停止循环,但它不会中止方法执行,因此最后一行将被执行并且实际上将看到"看不到我的文本".
@DamirZekić返回null并且收益率突破**不是**相同.如果你返回null然后你可以得到一个'NullReferenceException`获取IEnumerable的枚举器,而你可以得到yield break(没有元素的实例).
在上面的示例中,它可以简单地"break"而不是"yield break"吗?编译器没有抱怨.
@BrunoCosta尝试在同一方法中定期返回会产生编译错误.使用`yield return x`警告编译器,你希望这个方法是用于创建`Enumerator`对象的语法糖.这个枚举器有方法`MoveNext()`和属性`Current`.MoveNext()执行该方法,直到`yield return`语句,并将该值转换为"Current".下次调用MoveNext时,从那里继续执行.`yield break`将Current设置为null,表示此枚举器的结束,以便`foreach(myEnum()中的var x)将结束.
@DamirZekić你能否补充一下为什么你应该选择收益率突破回报以及两者有什么不同?
@deadManN你会使用`yield break`来无条件地跳过剩余的`yield return`s.

2> Brian..:

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


[+1] - 虽然在学术上没有.NET中的迭代器.只有普查员(一个方向,前进.)

3> Trap..:

告诉迭代器它已到达终点.

举个例子:

public interface INode
{
    IEnumerable GetChildren();
}

public class NodeWithTenChildren : INode
{
    private Node[] m_children = new Node[10];

    public IEnumerable GetChildren()
    {
        for( int n = 0; n < 10; ++n )
        {
            yield return m_children[ n ];
        }
    }
}

public class NodeWithNoChildren : INode
{
    public IEnumerable GetChildren()
    {
        yield break;
    }
}



4> 小智..:

yield基本上使一个IEnumerable方法的行为类似于一个合作(而不是先发制人)调度的线程.

yield return就像一个调用"schedule"或"sleep"函数的线程来放弃对CPU的控制.就像一个线程一样,该IEnumerable方法在紧接着的时刻重新获得控制,所有局部变量具有与放弃控制之前相同的值.

yield break 就像一个线程到达其功能的终点并终止.

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



5> Marc Gravell..:

在Jon Skeet的C#深度书中,这个免费的样本章节详细介绍了迭代器块的整个主题.



6> Wallace Kell..:

yield break语句导致枚举停止.实际上,yield break完成枚举而不返回任何其他项.

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

IEnumerable 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 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(..).



7> 小智..:

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

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

和解释,如果yield break在方法中命中一个语句,该方法的执行将停止而不返回.有一些时间情况,当你不想给出任何结果时,你可以使用yield break.



8> John ClearZ..:

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

例如

// returns 1,2,3,4,5
IEnumerable 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;
 }

推荐阅读
雯颜哥_135
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有