为什么更喜欢收益而不是简单回报呢
本文关键字:简单 回报 更喜欢 收益 为什么 | 更新日期: 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,因为编译器将处理构建可枚举的,而不必首先构建列表。所以对我来说,如果我有已经实现接口的东西,那么我会返回,如果我必须构建它,而不在其他地方使用它,那么我就会返回。