为什么更喜欢收益而不是简单回报呢

本文关键字:简单 回报 更喜欢 收益 为什么 | 更新日期: 2023-09-27 17:59:28

我正在尝试理解使用Yield枚举集合。我写了这个基本代码:

static void Main(string[] args)
{
    Iterate iterate = new Iterate();
    foreach (int i in iterate.EnumerateList())
    {
        Console.Write("{0}", i);
    }
    Console.ReadLine();
}
class Iterate
{
    public IEnumerable<int> EnumerateList()
    {
        List<int> lstNumbers = new List<int>();
        lstNumbers.Add(1);
        lstNumbers.Add(2);
        lstNumbers.Add(3);
        lstNumbers.Add(4);
        lstNumbers.Add(5);
        foreach (int i in lstNumbers)
        {
            yield return i;
        }
    }
}

(1) 如果我简单地使用return i而不是yield return i会怎样?

(2) 使用Yield的优点是什么?何时更喜欢使用Yield?

已编辑**

在上面的代码中,我认为两次使用foreach是一种开销。首先在main function中,第二在EnumerateList方法中。

为什么更喜欢收益而不是简单回报呢

使用yield return i使此方法成为迭代器。它将从您的整个循环中创建一个IEnumerable<int>值序列。

如果使用return i,它将只返回一个int值。在您的情况下,这将导致编译器错误,因为方法的返回类型是IEnumerable<int>,而不是int

在这个特定的例子中,我个人只返回lstNumbers,而不使用迭代器。不过,您可以在没有列表的情况下将其重写为:

public IEnumerable<int> EnumerateList()
{
    yield return 1;
    yield return 2;
    yield return 3;
    yield return 4;
    yield return 5;
}

甚至:

public IEnumerable<int> EnumerateList()
{
    for (int i=1;i<=5;++i)
        yield return i;
}

当你制作一个类时,这非常方便,你想把它当作一个集合。手工为自定义类型实现IEnumerable<T>通常需要创建一个自定义类等。在迭代器之前,这需要大量代码,如在C#中实现自定义集合的旧示例所示。

正如Reed所说,使用yield可以实现迭代器。迭代器的主要优点是它允许延迟求值。也就是说,除非需要,否则不必实现整个结果。

考虑BCL中的Directory.GetFiles。返回string[]。也就是说,在返回之前,它必须获取所有文件并将名称放入一个数组中。相反,CCD_ 17返回CCD_。也就是说,调用者负责处理结果集。这意味着调用者可以在任何时候选择不枚举集合。

yield关键字将使编译器将函数转换为枚举器对象。

yield return语句并不是简单地退出函数并返回一个值,而是使代码处于一种状态,以便在从枚举器请求下一个值时可以恢复该状态。

不能只返回i,因为i是int而不是IEnumerable。它甚至不会编译。您本可以返回lstNumbers,因为它实现了IEnumerable的接口。

我更喜欢yield return,因为编译器将处理构建可枚举的,而不必首先构建列表。所以对我来说,如果我有已经实现接口的东西,那么我会返回,如果我必须构建它,而不在其他地方使用它,那么我就会返回。