C# 什么时候是';收益率';真的需要吗?

C# 什么时候是';收益率';真的需要吗?,c#,yield,C#,Yield,可能重复: 什么是C#yield的真正用例 谢谢。当你需要的时候 在大多数情况下,这是有意义的,因为替代方法是构造一个临时集合 考虑这个场景:我有一个整数列表,我想列出它们的平方 我可以这样做: public static IEnumerable<int> Squares(this IEnumerable<int> numbers) { List<int> squares = new List<int>(); foreach (i

可能重复:

什么是C#yield的真正用例

谢谢。

当你需要的时候

在大多数情况下,这是有意义的,因为替代方法是构造一个临时集合

考虑这个场景:我有一个整数列表,我想列出它们的平方

我可以这样做:

public static IEnumerable<int> Squares(this IEnumerable<int> numbers) {
    List<int> squares = new List<int>();
    foreach (int number in numbers)
        squares.Add(number * number);

    return squares;
}
IEnumerable<int> numbers = GetLotsOfNumbers();
var squares = numbers.Squares();
int firstBigSquare = squares
    .Where(x => x >= 1000)
    .FirstOrDefault();
在开始处理非常大的集合之前,这一点可能并不明显,因为填充临时集合是非常浪费的

例如,假设我想找到高于某个阈值的第一个正方形。我可以这样做:

public static IEnumerable<int> Squares(this IEnumerable<int> numbers) {
    List<int> squares = new List<int>();
    foreach (int number in numbers)
        squares.Add(number * number);

    return squares;
}
IEnumerable<int> numbers = GetLotsOfNumbers();
var squares = numbers.Squares();
int firstBigSquare = squares
    .Where(x => x >= 1000)
    .FirstOrDefault();
IEnumerable numbers=GetLotsOfNumbers();
var squares=数字。squares();
int firstBigSquare=squares
。其中(x=>x>=1000)
.FirstOrDefault();
但是,如果我的
方法在返回之前填充了整个
列表
,则上述代码可能会做的工作远远超出需要。

来自:

在迭代器块中用于向枚举器对象提供值或发出迭代结束的信号

您可以在创建自定义迭代器时使用它。使用页面中的示例:

// yield-example.cs
using System;
using System.Collections;
public class List
{
    public static IEnumerable Power(int number, int exponent)
    {
        int counter = 0;
        int result = 1;
        while (counter++ < exponent)
        {
            result = result * number;
            yield return result;
        }
    }

    static void Main()
    {
        // Display powers of 2 up to the exponent 8:
        foreach (int i in Power(2, 8))
        {
            Console.Write("{0} ", i);
        }
    }
}
//yield-example.cs
使用制度;
使用系统集合;
公共班级名单
{
公共静态IEnumerable幂(整数,整数指数)
{
int计数器=0;
int结果=1;
while(计数器+++<指数)
{
结果=结果*编号;
收益结果;
}
}
静态void Main()
{
//显示指数8之前的2的幂:
foreach(int i掌权(2,8))
{
Console.Write(“{0}”,i);
}
}
}

yield
意味着
while
循环在
Power
中有效地在每次迭代后“暂停”以允许调用例程执行某些操作。在这种情况下,打印出结果。

当您懒得自己写时;)

Yield充当一个返回占位符——它是一个非本地的goto返回点,它保留了方法的环境,并允许代码“跳转”回去。在某种程度上,闭包与将委托传递给方法类似(有点颠倒),方法允许您在另一个方法中注入特定的逻辑,闭包允许您围绕一个更通用的方法执行不同类型的工作,允许您保持代码的小型化、模块化和可重用性


这可能会产生更高效的代码。与其实例化一个非常大的集合,还可以允许按顺序对单个对象进行操作(并且在每次操作后丢弃它们)。我想你可以构造一个简单的迭代器非常难以构建的情况。

+1我觉得我总是太懒了……应该注意的是,IEnumerator和IEnumerable之间有一个区别。这些词的拼写非常相似,我过去常常会感到困惑,因为我读的是不同的定义因为我的想法是一样的thing@Davy8真的!许多人对这种差异感到困惑。IEnumerator包含隐藏在收益背后的所有逻辑;IEnumerable只提供对IEnumerable的访问。IEnumerator能代替yield功能吗?@NewB这就是我所说的IEnumerable和IEnumerable之间的混淆。IEnumerable是人们通常使用的,它是一个值的顺序集合,使用IEnumerable可以无限长。IEnumerATOR告诉foreach如何在指定的IEnumerABLEJustin Ethernedge中获取下一个值。Ethernedge在TekPub Mastering LINQ系列中非常好地解释了这一点。写得很好的例子1了解差异可能不明显的原因。