受到另一个关于缺失Zip函数的问题的启发:
为什么在IEnumerable接口上没有ForEach扩展方法?或在任何地方吗?唯一获得ForEach方法的类是List<>。有什么原因吗,也许是性能?
受到另一个关于缺失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
其他回答
我的版本是一个扩展方法,允许你在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;
});
}
}
我想对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?
部分原因是语言设计者从哲学角度不同意这一观点。
没有(和测试……)一个功能比有一个功能更省事。 它并不是真的更短(有一些传递函数的情况下,它是,但这不是主要用途)。 它的目的是产生副作用,这不是linq的目的。 为什么要用另一种方式来做我们已经拥有的功能呢?(为每一个关键字)
https://blogs.msdn.microsoft.com/ericlippert/2009/05/18/foreach-vs-foreach/
是我还是List<T>。Foreach几乎被Linq淘汰了。 最初有
foreach(X x in Y)
其中Y必须是IEnumerable (Pre 2.0),并实现GetEnumerator()。 如果您查看生成的MSIL,您可以看到它与
IEnumerator<int> enumerator = list.GetEnumerator();
while (enumerator.MoveNext())
{
int i = enumerator.Current;
Console.WriteLine(i);
}
(MSIL见http://alski.net/post/0a-for-foreach-forFirst-forLast0a-0a-.aspx)
然后在DotNet2.0中出现了泛型和列表。我一直觉得Foreach是访问者模式的实现(参见Gamma, Helm, Johnson, Vlissides的设计模式)。
当然,在3.5中,我们可以使用Lambda来达到同样的效果,举个例子 http://dotnet-developments.blogs.techtarget.com/2008/09/02/iterators-lambda-and-linq-oh-my/