受到另一个关于缺失Zip函数的问题的启发:
为什么在IEnumerable接口上没有ForEach扩展方法?或在任何地方吗?唯一获得ForEach方法的类是List<>。有什么原因吗,也许是性能?
受到另一个关于缺失Zip函数的问题的启发:
为什么在IEnumerable接口上没有ForEach扩展方法?或在任何地方吗?唯一获得ForEach方法的类是List<>。有什么原因吗,也许是性能?
当前回答
我自己也一直在想,这就是为什么我总是带着这个:
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);
}
}
不错的扩展方法。
其他回答
@Coincoin
foreach扩展方法的真正功能包括Action<>的可重用性,而无需向代码添加不必要的方法。假设您有10个列表,并且您希望对它们执行相同的逻辑,而对应的函数不适合您的类并且不能重用。您可以将所有逻辑保存在一个地方,而不是使用十个for循环,或者使用一个显然不属于helper的通用函数(Action<>。所以,很多行被替换成
Action<blah,blah> f = { foo };
List1.ForEach(p => f(p))
List2.ForEach(p => f(p))
等等……
逻辑是在一个地方,你没有污染你的课。
在该语言中已经包含了一个foreach语句,它在大多数情况下都可以完成这项工作。
我不希望看到以下情况:
list.ForEach( item =>
{
item.DoSomething();
} );
而不是:
foreach(Item item in list)
{
item.DoSomething();
}
后者在大多数情况下更清晰,更容易阅读,尽管可能要长一点打字。
然而,我必须承认我在这个问题上改变了立场;ForEach()扩展方法在某些情况下确实很有用。
下面是语句和方法之间的主要区别:
类型检查:foreach在运行时完成,foreach()在编译时完成(大加分!) 调用委托的语法确实简单得多:objects.ForEach(DoSomething); ForEach()可以被链接:尽管这样一个特性的邪恶/有用还有待讨论。
这些都是很多人提出的很好的观点,我可以理解为什么人们忽略了这个功能。我不介意微软在下一个框架迭代中添加标准ForEach方法。
如果你有f#(它将在。net的下一个版本中),你可以使用
Seq。iter doSomething myIEnumerable
一种解决方法是编写. tolist()。ForEach(x =>…)
pros
易于理解——读者只需要知道c#附带了什么,而不需要知道任何额外的扩展方法。
语法干扰非常温和(只添加了一点无关的代码)。
通常不需要额外的内存,因为本机. foreach()必须实现整个集合。
cons
操作顺序并不理想。我宁愿实现一个元素,然后付诸行动,然后重复。这段代码首先实现所有元素,然后依次对它们进行操作。
如果意识到列表抛出异常,则永远无法对单个元素进行操作。
如果枚举数是无限的(就像自然数一样),那么你就不走运了。
我自己也一直在想,这就是为什么我总是带着这个:
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);
}
}
不错的扩展方法。