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一样。如果你在列表中间插入(通过插入),它会在枚举时返回它们在列表中存在的顺序。“除非需要,否则不必具体化整个结果”?如果要返回数组,需要先填充整个数组,然后才能返回。使用迭代器,每次返回一个元素,因此可以根据需要完成获取元素所需的任何工作。