我在MSDN中见过这种语法:yield break,但我不知道它是做什么的。有人知道吗?
当前回答
yield关键字与return关键字一起使用,为枚举器对象提供一个值。Yield return指定返回的值。当到达yield return语句时,存储当前位置。下次调用迭代器时,从这个位置重新开始执行。
用一个例子来解释它的意思:
public IEnumerable<int> SampleNumbers() { Int counter = 0; 收益回报计数器; 计数器=计数器+ 2; 收益回报计数器; 计数器=计数器+ 3; 收益回报计数器; }
迭代时返回的值为:0,2,5。
值得注意的是,本例中的counter变量是一个局部变量。在第二次迭代返回值2之后,第三次迭代从之前的位置开始,同时保留名为counter的局部变量之前的值2。
其他回答
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。
它指定迭代器已经结束。您可以将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");
在这种情况下,最后一条语句永远不会执行,因为我们提前离开了函数。
yield关键字与return关键字一起使用,为枚举器对象提供一个值。Yield return指定返回的值。当到达yield return语句时,存储当前位置。下次调用迭代器时,从这个位置重新开始执行。
用一个例子来解释它的意思:
public IEnumerable<int> SampleNumbers() { Int counter = 0; 收益回报计数器; 计数器=计数器+ 2; 收益回报计数器; 计数器=计数器+ 3; 收益回报计数器; }
迭代时返回的值为:0,2,5。
值得注意的是,本例中的counter变量是一个局部变量。在第二次迭代返回值2之后,第三次迭代从之前的位置开始,同时保留名为counter的局部变量之前的值2。
除了其他好的答案外,请注意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
yield基本上使IEnumerable<T>方法的行为类似于协作(而不是抢先)调度线程。
yield return就像一个线程调用“schedule”或“sleep”函数来放弃对CPU的控制。就像线程一样,IEnumerable<T>方法在结束后立即恢复控制,所有局部变量的值与放弃控制之前的值相同。
屈服断裂就像一个线程到达其功能的末端并终止。
人们谈论“状态机”,但状态机其实就是“线程”。一个线程有一些状态(即局部变量的值),每次调度它都会采取一些操作来达到一个新的状态。yield的关键在于,与我们所习惯的操作系统线程不同,使用它的代码在迭代被手动推进或终止之前是固定的。
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 为什么Visual Studio 2015/2017/2019测试运行器没有发现我的xUnit v2测试
- 如何使用JSON确保字符串是有效的JSON。网
- AppSettings从.config文件中获取值
- 通过HttpClient向REST API发布一个空体
- 如何检查IEnumerable是否为空或空?
- 自动化invokerrequired代码模式
- 没有ListBox。SelectionMode="None",是否有其他方法禁用列表框中的选择?
- 在c#代码中设置WPF文本框的背景颜色
- 在c#中,什么是单子?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- c#线程安全快速(est)计数器
- 如何将此foreach代码转换为Parallel.ForEach?
- 如何在iis7应用程序池中设置。net Framework 4.5版本