foreach是否在每次迭代时都评估数组?

foreach是否在每次迭代时都评估数组?,第1张

foreach是否在每次迭代时都评估数组

我只是以此来嘲笑你的代码

foreach(var v in Enumerable.Range(1,10).Skip(1))    v.Dump();

这是生成的IL。

IL_0001:  nop         IL_0002:  ldc.i4.1    IL_0003:  ldc.i4.s    0A IL_0005:  call        System.Linq.Enumerable.RangeIL_000A:  ldc.i4.1    IL_000B:  call        System.Linq.Enumerable.Skip//Call to SkipIL_0010:  callvirt    System.Collections.Generic.IEnumerable<System.Int32>.GetEnumeratorIL_0015:  stloc.1     // CS
Skip
00IL_0016: br.s IL_0026IL_0018: ldloc.1 // CS
IEnumerator<int> e = ((IEnumerable<int>)values).GetEnumerator();//Get the enumeratortry{  int m;//This variable is here prior to c#5.0  while(e.MoveNext())  {//int m; is declared here starting from c#5.0    m = (int)(int)e.Current;    //Your pre here  }}finally{  if (e != null) ((IDisposable)e).Dispose();}
00IL_0019: callvirt System.Collections.Generic.IEnumerator<System.Int32>.get_CurrentIL_001E: stloc.0 // vIL_001F: ldloc.0 // vIL_0020: call LINQPad.Extensions.DumpIL_0025: pop IL_0026: ldloc.1 // CS
VeryLongRunningMethodThatReturnsEnumerable
00IL_0027: callvirt System.Collections.IEnumerator.MoveNextIL_002C: stloc.2 // CS
foreach(var obj in VeryLongRunningMethodThatReturnsEnumerable()){   //Do something with that obj}
01IL_002D: ldloc.2 // CS01IL_002E: brtrue.s IL_0018IL_0030: leave.s IL_0042IL_0032: ldloc.1 // CS00IL_0033: ldnull IL_0034: ceq IL_0036: stloc.2 // CS01IL_0037: ldloc.2 // CS01IL_0038: brtrue.s IL_0041IL_003A: ldloc.1 // CS00IL_003B: callvirt System.IDisposable.DisposeIL_0040: nop IL_0041: endfinally

如您所见,仅被调用一次。

等效的C#代码看起来像这样

考虑下面的代码,如果foreach
在每次迭代中调用,那将是一场噩梦。语言设计中的巨大缺陷。幸运的是它没有那样做。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5440841.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存