请您举一个C#中急切评估的延期执行示例?
我从MSDN上读到LINQ中的延迟执行可以通过惰性或急切评估来实现。我可以在互联网上找到延迟执行延迟执行的示例,但是我找不到任何关于延迟执行的示例,并且热切评估。
此外,延迟执行与懒惰评估有何不同?在我看来,两者看起来都一样。你能为此提供任何一个例子吗?
答案 0 :(得分:44)
另外Wikipedia假设应该为延迟评估维护三个规则,并且在MSDN中不尊重第三个点,这意味着如果再次调用GetEnumerator
,表达式将被多次评估(由spec使用yield
关键字生成的枚举器对象上没有实现重置,并且大多数linq当前都使用它
考虑功能
int Computation(int index)
IEnumerable<int> GetComputation(int maxIndex)
{
var result = new int[maxIndex];
for(int i = 0; i < maxIndex; i++)
{
result[i] = Computation(i);
}
return result;
}
Computation
执行maxIndex
次GetEnumerator
返回枚举器的新实例,不再执行任何操作。MoveNext
都会将存储在下一个数据单元格中的值放在Current
的{{1}}成员中,这就是全部。费用:大前期,枚举期间小(仅限副本)
IEnumerator
IEnumerable<int> GetComputation(int maxIndex)
{
var result = new int[maxIndex];
for(int i = 0; i < maxIndex; i++)
{
result[i] = Computation(i);
}
foreach(var value in result)
{
yield return value;
}
}
的参数(IEnumerable
)的副本maxIndex
返回枚举器的新实例,不再执行任何操作。GetEnumerator
执行maxIndex乘以compute方法,将结果存储在数组中,MoveNext
将返回第一个值。Current
的调用都会在MoveNext
中输入存储在数组中的值。费用:没有预先设定,枚举开始时为大,枚举期间为小(仅限副本)
Current
IEnumerable<int> GetComputation(int maxIndex)
{
for(int i = 0; i < maxIndex; i++)
{
yield return Computation(i);
}
}
返回枚举器的新实例,不再执行任何操作。GetEnumerator
都会执行MoveNext
代码,将值放入Computation
并让调用者立即对结果执行操作。linq的大多数都使用延迟和延迟执行,但有些函数不能像排序那样。
费用:没有预先设定,在枚举期间适度(计算在那里执行)
Current
或创建MoveNext
实例时完成(对于IEnumerator
,它是IEnumerable
时GetEnumerator
1}}被称为)MoveNext
时都会完成工作,但之前没有。Parallel LINQ做的有点不同,因为从调用者的角度来看,计算可以被认为是延迟/懒惰,但是在内部,一旦枚举开始,一些元素的计算就会并行开始。结果是,如果下一个值已经存在,则立即得到它,否则你将不得不等待它。
答案 1 :(得分:1)
您可以急切地评估延迟执行IEnumerable的一种方法是使用linq的.ToArray()函数将其转换为数组。
var evaluated = enumerable.ToArray();
这会强制评估完整的可枚举数,然后你就拥有了你可以做任何你想做的数组。