受到另一个关于缺失Zip函数的问题的启发:
为什么在IEnumerable接口上没有ForEach扩展方法?或在任何地方吗?唯一获得ForEach方法的类是List<>。有什么原因吗,也许是性能?
受到另一个关于缺失Zip函数的问题的启发:
为什么在IEnumerable接口上没有ForEach扩展方法?或在任何地方吗?唯一获得ForEach方法的类是List<>。有什么原因吗,也许是性能?
当前回答
我想对Aku的回答进行进一步阐述。
如果你想调用一个方法的唯一目的是它的副作用,而不是首先迭代整个枚举对象,你可以使用这个:
private static IEnumerable<T> ForEach<T>(IEnumerable<T> xs, Action<T> f) {
foreach (var x in xs) {
f(x); yield return x;
}
}
其他回答
在3.5中,所有添加到IEnumerable中的扩展方法都是为了支持LINQ(注意它们是在System.Linq.Enumerable类中定义的)。在这篇文章中,我解释了为什么foreach不属于LINQ: 现有的LINQ扩展方法类似于Parallel.For?
我的版本是一个扩展方法,允许你在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;
});
}
}
@Coincoin
foreach扩展方法的真正功能包括Action<>的可重用性,而无需向代码添加不必要的方法。假设您有10个列表,并且您希望对它们执行相同的逻辑,而对应的函数不适合您的类并且不能重用。您可以将所有逻辑保存在一个地方,而不是使用十个for循环,或者使用一个显然不属于helper的通用函数(Action<>。所以,很多行被替换成
Action<blah,blah> f = { foo };
List1.ForEach(p => f(p))
List2.ForEach(p => f(p))
等等……
逻辑是在一个地方,你没有污染你的课。
大多数LINQ扩展方法都返回结果。ForEach不符合这个模式,因为它什么也不返回。
当你想要返回一些东西时,你可以使用select。 如果不需要,可以先使用ToList,因为您可能不想修改集合中的任何内容。