受到另一个关于缺失Zip函数的问题的启发:
为什么在IEnumerable接口上没有ForEach扩展方法?或在任何地方吗?唯一获得ForEach方法的类是List<>。有什么原因吗,也许是性能?
受到另一个关于缺失Zip函数的问题的启发:
为什么在IEnumerable接口上没有ForEach扩展方法?或在任何地方吗?唯一获得ForEach方法的类是List<>。有什么原因吗,也许是性能?
当前回答
还没有人指出ForEach<T>导致编译时类型检查,其中ForEach关键字是运行时检查的。
在代码中使用了这两个方法之后,我做了一些重构,我倾向于. foreach,因为我必须查找测试失败/运行时失败来找到foreach问题。
其他回答
我自己也一直在想,这就是为什么我总是带着这个:
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问题。
在该语言中已经包含了一个foreach语句,它在大多数情况下都可以完成这项工作。
我不希望看到以下情况:
list.ForEach( item =>
{
item.DoSomething();
} );
而不是:
foreach(Item item in list)
{
item.DoSomething();
}
后者在大多数情况下更清晰,更容易阅读,尽管可能要长一点打字。
然而,我必须承认我在这个问题上改变了立场;ForEach()扩展方法在某些情况下确实很有用。
下面是语句和方法之间的主要区别:
类型检查:foreach在运行时完成,foreach()在编译时完成(大加分!) 调用委托的语法确实简单得多:objects.ForEach(DoSomething); ForEach()可以被链接:尽管这样一个特性的邪恶/有用还有待讨论。
这些都是很多人提出的很好的观点,我可以理解为什么人们忽略了这个功能。我不介意微软在下一个框架迭代中添加标准ForEach方法。
这里的讨论给出了答案:
实际上,我所看到的具体讨论确实取决于功能的纯洁性。在一个表达式中,经常会有关于没有副作用的假设。使用ForEach是特别吸引副作用,而不仅仅是忍受它们。——基思·法默(合伙人)
基本上,这个决定是为了保持扩展方法在功能上的“纯粹”。ForEach在使用Enumerable扩展方法时会产生副作用,这不是目的。
在3.5中,所有添加到IEnumerable中的扩展方法都是为了支持LINQ(注意它们是在System.Linq.Enumerable类中定义的)。在这篇文章中,我解释了为什么foreach不属于LINQ: 现有的LINQ扩展方法类似于Parallel.For?