.Net – 什么时候是List .ForEach优先于标准的foreach循环?

通用列表类具有.ForEach(Action action)方法。 现在我已经完成了一些关于它们如何表现的简单时间,似乎通用的ForEach是较差的表演者。 (Snippet Compiler Friendly)代码如下 –

 public static class timer{ public static long foreachloop = 0; public static long Gforeachloop = 0;} public class something{ public List myStrings = new List(); public something() { for(int i = 1; i<=5000000;i++) { myStrings.Add(i.ToString()); } }} public class cls1{ private static List Strings = new List(); private static List OtherStrings = new List(); public static void RunSnippet() { something s = new something(); Stopwatch watch = new Stopwatch(); watch.Start(); foreach(string x in s.myStrings) { Strings.Add(x); } watch.Stop(); timer.foreachloop = watch.ElapsedMilliseconds; watch.Reset(); watch.Start(); s.myStrings.ForEach(delegate(string n){OtherStrings.Add(n);}); s.myStrings.Clear(); watch.Stop(); timer.Gforeachloop = watch.ElapsedMilliseconds; WL("FOREACH-"+timer.foreachloop + ",Count = " + Strings.Count); WL("GFOREACH-"+timer.Gforeachloop + ",Count = " + OtherStrings.Count); } #region Helper methods public static void Main() { try { RunSnippet(); } catch (Exception e) { string error = string.Format("---\nThe following error occurred while executing the snippet:\n{0}\n---", e.ToString()); Console.WriteLine(error); } finally { Console.Write("Press any key to continue..."); Console.ReadKey(); } } private static void WL(object text, params object[] args) { Console.WriteLine(text.ToString(), args); } private static void RL() { Console.ReadLine(); } private static void Break() { System.Diagnostics.Debugger.Break(); } #endregion } 

FOREACH出现在177ms,GFOREACH出现在707ms。

现在我猜这是使用它的一个很好的理由,但我想不出一个。 显然,性能不是原因所以问题是何时它是最佳选择?

提前致谢。

这篇来自Eric Lippert的博客文章给出了背景:

http://blogs.msdn.com/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx

他正在讨论扩展方法的常见建议, IEnumerable做同样的事情,但哲学上的反对也适用于List.ForEach

这表明也许这种方法从来都不是一个好主意,尽管它看起来很“酷”。 使用foreach更清楚。

我已经建议这样的方法可以被认为是经典的闭包循环变量bug的修复 。

但在实践中,我只是更好地发现了这样的错误。

当它看起来更整洁。

根本不是开玩笑。 真的,我的意思是。 在您的情况下,使用更易读的样式。 例如,如果您只想在每个项目上调用方法,例如:

 list.ForEach(Console.WriteLine); 

这种风格更适合。 但是,如果你有一百行作为循环体,或者你有嵌套循环和控制流结构,旧样式看起来更好。