推迟执行和急切评估
您能否给我一个延期执行的例子,用C#进行急切的评估?
我从MSDN读到,LINQ中的延迟执行可以通过懒惰或急切的评估来实现。 我可以在因特网上找到延迟执行的例子,但我找不到任何延迟执行的例子。
此外,延期执行与懒惰评估有何不同? 在我看来,两者看起来都一样。 你能提供任何例子吗?
贝娄是我的回答,但也注意到Jon Skeet今天在他的博客上谈到了这个事实,即他对MSDN的“懒惰”含义并不完全确定,因为MSDN并没有真正清楚他们使用时的懒惰究竟是什么意思它在你只是多么懒惰? 他的帖子让人感兴趣的阅读。
此外,维基百科假设应该为延迟评估维护三条规则,第三点在MSDN中不受尊重,因为如果再次调用GetEnumerator
,表达式将被多次评估(由于规范Reset未在使用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
将存储在下一个数组单元格中的值存储在IEnumerator
的Current
成员中,就这些了。 成本 :在枚举期间大前期,小(仅限副本)
延期但急切的执行
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
返回一个新的枚举数实例。 MoveNext
执行计算方法的maxIndex次,将结果存储在数组中, Current
将返回第一个值。 MoveNext
都会将Current
存储在数组中的值存入Current
值。 成本 :无预付款,枚举开始时为大,枚举期间为小(仅为副本)
延期执行和延迟执行
IEnumerable<int> GetComputation(int maxIndex)
{
for(int i = 0; i < maxIndex; i++)
{
yield return Computation(i);
}
}
GetEnumerator
返回一个新的枚举数实例。 MoveNext
执行一次Computation
代码,将该值放入Current
值并让调用者立即处理结果。 linq大部分使用延迟和懒惰执行,但一些函数不能像排序那样。
成本 :无预付费,枚举期间中等(计算在那里执行)
总结
MoveNext
或创建IEnumerator
实例时完成(对于IEnumerable
它是在调用GetEnumerator
时完成的) MoveNext
都会完成该工作,但之前没有任何操作。 并行LINQ做的有点不同,因为从调用者的角度来看,计算可以被认为是延迟/懒惰,但是一旦枚举开始,内部计算一些元素就会并行开始。 结果是,如果下一个值已经在那里,你立即得到它,否则你将不得不等待它。
您可以急切地评估延迟执行IEnumerable的一种方法是使用linq的.ToArray()函数将其简单地转换为数组。
var evaluated = enumerable.ToArray();
这迫使完全枚举的评估,然后你有数组,你可以做任何你想要的。
链接地址: http://www.djcxy.com/p/53705.html