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

第一类型:

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>
});

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


当前回答

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>

其他回答

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

你可以把第二个写成

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

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

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

在幕后,匿名委托被转换为一个实际的方法,因此如果编译器没有选择内联函数,那么第二个选择可能会有一些开销。此外,匿名委托示例主体引用的任何局部变量在本质上都会发生变化,因为编译器会使用一些技巧来隐藏它被编译为新方法的事实。这里有更多关于c#如何做到这一点的信息:

http://blogs.msdn.com/oldnewthing/archive/2006/08/04/688527.aspx

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>

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

我猜somlist . foreach()调用可以很容易地并行化,而正常的foreach不那么容易并行运行。 您可以很容易地在不同的核心上运行几个不同的委托,这对于普通的foreach来说并不容易做到。 这只是我的小意思