C# 为什么偏好收益率而非简单回报率?
我试图理解使用收益率来列举集合。我编写了以下基本代码:C# 为什么偏好收益率而非简单回报率?,c#,C#,我试图理解使用收益率来列举集合。我编写了以下基本代码: static void Main(string[] args) { Iterate iterate = new Iterate(); foreach (int i in iterate.EnumerateList()) { Console.Write("{0}", i); } Console.ReadLine(); } class Iterate { public IEnum
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;
}
}
}
static void Main(字符串[]args)
{
迭代迭代=新迭代();
foreach(iterate.EnumerateList()中的int i)
{
Console.Write(“{0}”,i);
}
Console.ReadLine();
}
类迭代
{
公共IEnumerable枚举列表()
{
列表编号=新列表();
增加(1);
增加(2);
增加(3);
增加(4);
增加(5);
foreach(整数i,以数字表示)
{
收益率i;
}
}
}
(1) 如果我只是使用返回I
而不是产生返回I
,会怎么样
(2) 使用收益率的优势是什么?何时更喜欢使用收益率
已编辑**
在上面的代码中,我认为两次使用
foreach
是一种开销。第一个在主函数中
第二个在枚举列表中
方法中。使用收益率i
使此方法成为一种新方法。它将从整个循环中创建一个IEnumerable
值序列
如果使用returni
,它只会返回一个int
值。在您的情况下,这将导致编译器错误,因为方法的返回类型是IEnumerable
,而不是int
在这个特定的示例中,我个人只返回lstNumbers
,而不是使用迭代器。但是,您可以在没有列表的情况下重写此内容,如下所示:
public IEnumerable<int> EnumerateList()
{
yield return 1;
yield return 2;
yield return 3;
yield return 4;
yield return 5;
}
public IEnumerable枚举列表()
{
收益率1;
收益率2;
收益率3;
收益率4;
收益率5;
}
甚至:
public IEnumerable<int> EnumerateList()
{
for (int i=1;i<=5;++i)
yield return i;
}
public IEnumerable枚举列表()
{
对于(int i=1;i,yield
关键字将使编译器将函数转换为枚举器对象
yield return
语句并不是简单地退出函数并返回一个值,而是让代码处于一种状态,这样当从枚举器请求下一个值时,代码就可以在该点上恢复。您不能只返回i,因为i是int而不是IEnumerable。它甚至不会编译。您可以返回lstNumber实现IEnumerable接口的
我更喜欢生成返回,因为编译器将处理生成可枚举项的任务,而不必首先生成列表。因此,对于我来说,如果我已经实现了接口,那么我会返回,如果我必须生成它,而不在其他地方使用它,那么我将生成返回。正如里德所说,使用生成可以让您实现迭代器。迭代器的主要优点是它允许延迟计算。也就是说,除非需要,它不必具体化整个结果
考虑来自BCL的Directory.GetFiles
。它返回string[]
。也就是说,在返回之前,它必须获取所有文件并将名称放入数组中。与之相反,目录。EnumerateFiles
返回IEnumerable
。也就是说,调用方负责处理结果集。这意味着调用方可以选择在任何时候不枚举集合。返回I
导致编译器错误;i
不是IEnumerable
。以防我删除IEnumerable并在集合中循环,而不是使用IEnumerable和Yield。@RKh将返回第一个整数,并且永远没有机会返回任何其他整数。Yield return
可以在以下情况下提高性能:您不会遍历整个集合。在本例中,您可以只返回lstNumbers
。在.NET 4.0和.NET 4.5中是否仍然首选Yield?或者甚至使用返回可枚举的.Range(1,5)
@RKh这不是偏好的问题-如果您正在实现某个允许人们用作序列的东西,那么这是一种非常好的方法。@RKh否-它将按调用的顺序返回值。如果您想对它们进行排序,可以稍后进行排序。Yield将以相同的方式处理字符串-它将“Yield”每次当你做一个收益返回时,每个字符串。@ RKH是的,在这种情况下,因为列表的枚举器按这个顺序返回它们,就像你正在调用的Add一样。如果你在列表中间插入(通过插入),它会在枚举时返回它们在列表中存在的顺序。“除非需要,否则不必具体化整个结果”?如果要返回数组,需要先填充整个数组,然后才能返回。使用迭代器,每次返回一个元素,因此可以根据需要完成获取元素所需的任何工作。