Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么是;屈服断裂&引用;你用C#做什么?_C#_.net_Yield - Fatal编程技术网

什么是;屈服断裂&引用;你用C#做什么?

什么是;屈服断裂&引用;你用C#做什么?,c#,.net,yield,C#,.net,Yield,我在MSDN:中见过这种语法,但我不知道它的作用。有人知道吗?结束迭代器块(例如,表示IEnumerable中没有更多元素)。告诉迭代器它已到达末尾 例如: public interface INode { IEnumerable<Node> GetChildren(); } public class NodeWithTenChildren : INode { private Node[] m_children = new Node[10]; public

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

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

告诉迭代器它已到达末尾

例如:

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;
    }
}
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.");
}
公共接口INode
{
IEnumerable GetChildren();
}
公共类NodeWithTenChildren:INode
{
私有节点[]m_children=新节点[10];
公共IEnumerable GetChildren()
{
对于(int n=0;n<10;++n)
{
收益率m_子项[n];
}
}
}
公共类NodeWithNoChildren:INode
{
公共IEnumerable GetChildren()
{
屈服断裂;
}
}

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

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

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

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

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

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

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

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

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

下面是一个很好的例子:

public static IEnumerable<int> Range( int min, int max ) { while ( true ) { if ( min >= max ) { yield break; } yield return min++; } } 公共静态IEnumerable范围(最小整数、最大整数) { while(true) { 如果(最小值>=最大值) { 屈服断裂; } 收益率min++; } }
还有一个解释,如果在一个方法中命中了
yieldbreak
语句,则该方法的执行将停止而不返回。在某些情况下,当您不想给出任何结果时,可以使用yield break。

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

要使用示例来解释其含义,请执行以下操作:

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;
    }
}
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.");
}
public IEnumerable SampleNumbers()
{
int计数器=0;
收益返回计数器;
计数器=计数器+2;
收益返回计数器;
计数器=计数器+3;
收益返回计数器;
}
迭代时返回的值为:0、2、5


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

语句导致枚举停止。实际上,
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;
    }
}
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.");
}
请注意对
屈服中断的调用。实际上,它提前退出枚举


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

yield break只是表示最后一次返回,不返回任何值

e、 g

//返回1,2,3,4,5
IEnumerable CountToFive()
{
收益率1;
收益率2;
收益率3;
收益率4;
收益率5;
屈服断裂;
收益率6;
收益率7;
收益率8;
收益率9;
}

您没有解释什么是
收益率中断
我认为
收益率返回
实际上不支持返回多个值。也许这不是你真正的意思,但我就是这么理解的。Sam——具有多个yield-return语句的SampleNumbers方法实际上是有效的,迭代器的值会立即返回,并且在请求下一个值时会继续执行。我见过有人用“产量突破”来结束这种方法,但这是不必要的。命中方法的结尾也会结束迭代器这是
产量中断
的一个不好的例子,因为它不包含语言级枚举器,例如
foreach
——当使用枚举器时,
产量中断
提供实际值。这个例子看起来像一个展开的循环。在现实世界中,你几乎看不到这段代码(当然,我们都能想到一些边缘情况),而且,这里没有“迭代器”。作为语言规范,“迭代器块”不能扩展到方法之外。实际返回的是一个“可枚举的”,另请参见:Yield return不需要支持列表,也就是说,您不需要编写类似于
MyList的代码。添加(…)
只需执行
Yield return…
。如果您需要提前中断循环并返回虚拟支持列表,则使用
屈服中断;