IEnumerable是否必须使用Yield来延迟?
这是帮助我了解延期执行和收益的测试代码。
//immediate execution
public IEnumerable Power(int number, int howManyToShow)
{
var result = new int[howManyToShow];
result[0] = number;
for (int i = 1; i < howManyToShow; i++)
result[i] = result[i - 1] * number;
return result;
}
//deferred but eager
public IEnumerable PowerYieldEager(int number, int howManyToShow)
{
var result = new int[howManyToShow];
result[0] = number;
for (int i = 1; i < howManyToShow; i++)
result[i] = result[i - 1] * number;
foreach (var value in result)
yield return value;
}
//deferred and lazy
public IEnumerable PowerYieldLazy(int number, int howManyToShow)
{
int counter = 0;
int result = 1;
while (counter++ < howManyToShow)
{
result = result * number;
yield return result;
}
}
[Test]
public void Power_WhenPass2AndWant8Numbers_ReturnAnEnumerable()
{
IEnumerable listOfInts = Power(2, 8);
foreach (int i in listOfInts)
Console.Write("{0} ", i);
}
[Test]
public void PowerYieldEager_WhenPass2AndWant8Numbers_ReturnAnEnumerableOfInts()
{
//deferred but eager execution
IEnumerable listOfInts = PowerYieldEager(2, 8);
foreach (int i in listOfInts)
Console.Write("{0} ", i);
}
[Test]
public void PowerYield_WhenPass2AndWant8Numbers_ReturnAnEnumerableOfIntsOneAtATime()
{
//deferred and lazy execution
IEnumerable listOfInts = PowerYieldLazy(2, 8);
foreach (int i in listOfInts)
Console.Write("{0} ", i);
}
答案 0 :(得分:6)
使用yield
- 最终您可以通过编写自定义枚举器(yield
来完成{{1>}所做的一切 {1}})并将行动推迟到第一个IEnumerator[<T>]
。但是,实施起来非常痛苦。当然,如果您执行使用MoveNext()
,默认情况下会延迟实现(您可以使用两种方法使其不延迟 - 一种不使用yield
的方法,然后在访问数据之后使用另一个方法(迭代器块)来实现枚举器。
坦率地说,编写调查员很难并且错误。除非绝对必要,否则我会避免它迭代器块很棒。
答案 1 :(得分:1)
返回IEnumerable的函数(F1)可以返回在另一个函数(F2)中计算的IEnumerable,如果F2被延迟,则F1被推迟
例如,在以下代码中,F1和F2都是延迟的
public IEnumerable<int> F2()
{
for (int i = 0; i < 10; i++) {
yield return i;
}
}
public IEnumerable<int> F1()
{
return F2();
}
答案 2 :(得分:0)
延迟和渴望是对立的 - 懒惰只是延迟的同义词。
急切序列是预先计算的序列,例如列表或数组。延迟序列是在迭代时计算的序列。
在您的示例中,Power
非常渴望,因为它会计算一个数组并将其返回。这与PowerYieldEager
不同,后者在迭代生成的IEnumerable
之前不会构建数组。
您可以将延迟与渴望视为序列的潜在与序列的内容。考虑到这一点,yield return
只是推迟的一种方式;请求结果时计算的任何序列都是延迟序列。