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

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


当前回答

因此,有很多关于ForEach扩展方法不合适的评论,因为它不像LINQ扩展方法那样返回值。虽然这是事实陈述,但并不完全正确。

LINQ扩展方法都返回一个值,所以它们可以链接在一起:

collection.Where(i => i.Name = "hello").Select(i => i.FullName);

然而,仅仅因为LINQ是使用扩展方法实现的,并不意味着扩展方法必须以相同的方式使用并返回一个值。编写一个扩展方法来公开不返回值的常见功能是完全有效的使用。

关于ForEach的具体参数是,基于扩展方法的约束(即扩展方法永远不会覆盖具有相同签名的继承方法),可能存在这样一种情况,即自定义扩展方法在所有impelement IEnumerable<T> (List<T>除外)的类上可用。这可能会导致混淆,因为根据调用的是扩展方法还是继承方法,方法开始表现不同。

其他回答

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

虽然我同意在大多数情况下使用内置的foreach构造更好,但我发现在foreach <>扩展上使用这种变体比自己在常规foreach中管理索引要好一些:

public static int ForEach<T>(this IEnumerable<T> list, Action<int, T> action)
{
    if (action == null) throw new ArgumentNullException("action");

    var index = 0;

    foreach (var elem in list)
        action(index++, elem);

    return index;
}
Example
var people = new[] { "Moe", "Curly", "Larry" };
people.ForEach((i, p) => Console.WriteLine("Person #{0} is {1}", i, p));

会给你:

Person #0 is Moe
Person #1 is Curly
Person #2 is Larry

我的版本是一个扩展方法,允许你在T的IEnumerable上使用ForEach

public static class EnumerableExtension
{
        public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
    {
        source.All(x =>
        {
            action.Invoke(x);
            return true;
        });
    }
}

你可以这样写扩展方法:

// Possibly call this "Do"
IEnumerable<T> Apply<T> (this IEnumerable<T> source, Action<T> action)
{
    foreach (var e in source)
    {
        action(e);
        yield return e;
    }
}

Pros

允许链接:

MySequence
    .Apply(...)
    .Apply(...)
    .Apply(...);

Cons

它实际上不会做任何事情,直到你强制迭代。因此,它不应该被称为. foreach()。你可以在结尾写.ToList(),或者你也可以写这个扩展方法:

// possibly call this "Realize"
IEnumerable<T> Done<T> (this IEnumerable<T> source)
{
    foreach (var e in source)
    {
        // do nothing
        ;
    }

    return source;
}

这可能与发布的c#库有很大的不同;不熟悉您的扩展方法的读者将不知道如何理解您的代码。

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

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