显然有许多方法可以迭代集合。很好奇是否有什么不同,或者为什么你用一种方式而不是另一种。

第一类型:

List<string> someList = <some way to init>
foreach(string s in someList) {
   <process the string>
}

其他方式:

List<string> someList = <some way to init>
someList.ForEach(delegate(string s) {
    <process the string>
});

我想,除了我上面使用的匿名委托,你还可以指定一个可重用的委托。


当前回答

List.ForEach()被认为更具功能性。

List.ForEach()表示你想做什么。Foreach(列表中的项目)也确切地说明了你想要如何完成它。这就剩下List了。ForEach可以自由更改未来如何部分的实现。例如,一个假设的。net未来版本可能总是运行List。在并行的情况下,假设此时每个人都有一些cpu核心通常处于空闲状态。

另一方面,foreach (list中的项)让您对循环有更多的控制。例如,您知道项目将以某种顺序进行迭代,如果项目满足某些条件,则很容易在中间中断。


关于这个问题的一些最新评论可在此查阅:

https://stackoverflow.com/a/529197/3043

其他回答

您展示的第二种方法使用扩展方法为列表中的每个元素执行委托方法。

这样,您就有了另一个委托(=方法)调用。

此外,还可以使用for循环迭代列表。

你可以命名匿名委托:-)

你可以把第二个写成

someList.ForEach(s => s.ToUpper())

我更喜欢这个,而且节省了很多打字。

正如Joachim所说,并行性更容易应用于第二种形式。

整个ForEach作用域(委托函数)被视为一行代码(调用该函数),您不能设置断点或进入代码。如果发生未处理的异常,则标记整个块。

ForEach函数是泛型类List的成员。

我已经创建了以下扩展来复制内部代码:

public static class MyExtension<T>
    {
        public static void MyForEach(this IEnumerable<T> collection, Action<T> action)
        {
            foreach (T item in collection)
                action.Invoke(item);
        }
    }

因此,最后我们使用普通的foreach(如果你愿意,也可以使用循环for)。

另一方面,使用委托函数只是定义函数的另一种方式,以下代码:

delegate(string s) {
    <process the string>
}

等价于:

private static void myFunction(string s, <other variables...>)
{
   <process the string>
}

或者使用labda表达式:

(s) => <process the string>

我们这里有一些代码(在VS2005和c# 2.0中),以前的工程师用他们的方式使用列表。ForEach(delegate(item) {foo;});而不是foreach(item in list) {foo;};他们写的所有代码。例如,从dataReader读取行的代码块。

我还是不知道他们为什么要这么做。

list.ForEach()的缺点是:

It is more verbose in C# 2.0. However, in C# 3 onwards, you can use the "=>" syntax to make some nicely terse expressions. It is less familiar. People who have to maintain this code will wonder why you did it that way. It took me awhile to decide that there wasn't any reason, except maybe to make the writer seem clever (the quality of the rest of the code undermined that). It was also less readable, with the "})" at the end of the delegate code block. See also Bill Wagner's book "Effective C#: 50 Specific Ways to Improve Your C#" where he talks about why foreach is preferred to other loops like for or while loops - the main point is that you are letting the compiler decide the best way to construct the loop. If a future version of the compiler manages to use a faster technique, then you will get this for free by using foreach and rebuilding, rather than changing your code. a foreach(item in list) construct allows you to use break or continue if you need to exit the iteration or the loop. But you cannot alter the list inside a foreach loop.

看到这个名单我很惊讶。ForEach稍微快一点。但这可能不是贯穿始终的有效理由,那将是不成熟的优化。如果你的应用程序使用的是数据库或web服务,而不是循环控制,那么时间几乎总是会花在那里。你也用for循环测试过它吗?列表中。ForEach可以更快,因为在内部使用它,没有包装器的for循环甚至更快。

我不同意list.ForEach(委托)版本在任何重要方面都“更实用”。它确实将一个函数传递给另一个函数,但在结果或程序组织方面没有太大的区别。

我不认为每一项都是这样。“确切地说你想怎么做”- a for(int 1 = 0;I < count;i++)循环可以做到这一点,foreach循环将控制的选择留给编译器。

My feeling is, on a new project, to use foreach(item in list) for most loops in order to adhere to the common usage and for readability, and use list.Foreach() only for short blocks, when you can do something more elegantly or compactly with the C# 3 "=>" operator. In cases like that, there may already be a LINQ extension method that is more specific than ForEach(). See if Where(), Select(), Any(), All(), Max() or one of the many other LINQ methods doesn't already do what you want from the loop.