受到另一个关于缺失Zip函数的问题的启发:

为什么在IEnumerable接口上没有ForEach扩展方法?或在任何地方吗?唯一获得ForEach方法的类是List<>。有什么原因吗,也许是性能?


当前回答

我为此写了一篇博文: http://blogs.msdn.com/kirillosenkov/archive/2009/01/31/foreach.aspx

如果你想在。net 4.0中看到这个方法,你可以在这里投票: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=279093

其他回答

这里的讨论给出了答案:

实际上,我所看到的具体讨论确实取决于功能的纯洁性。在一个表达式中,经常会有关于没有副作用的假设。使用ForEach是特别吸引副作用,而不仅仅是忍受它们。——基思·法默(合伙人)

基本上,这个决定是为了保持扩展方法在功能上的“纯粹”。ForEach在使用Enumerable扩展方法时会产生副作用,这不是目的。

我自己也一直在想,这就是为什么我总是带着这个:

public static void ForEach<T>(this IEnumerable<T> col, Action<T> action)
{
    if (action == null)
    {
        throw new ArgumentNullException("action");
    }
    foreach (var item in col)
    {
        action(item);
    }
}

不错的扩展方法。

还没有人指出ForEach<T>导致编译时类型检查,其中ForEach关键字是运行时检查的。

在代码中使用了这两个方法之后,我做了一些重构,我倾向于. foreach,因为我必须查找测试失败/运行时失败来找到foreach问题。

当你想要返回一些东西时,你可以使用select。 如果不需要,可以先使用ToList,因为您可能不想修改集合中的任何内容。

我想对Aku的回答进行进一步阐述。

如果你想调用一个方法的唯一目的是它的副作用,而不是首先迭代整个枚举对象,你可以使用这个:

private static IEnumerable<T> ForEach<T>(IEnumerable<T> xs, Action<T> f) {
    foreach (var x in xs) {
        f(x); yield return x;
    }
}