受到另一个关于缺失Zip函数的问题的启发:
为什么在IEnumerable接口上没有ForEach扩展方法?或在任何地方吗?唯一获得ForEach方法的类是List<>。有什么原因吗,也许是性能?
受到另一个关于缺失Zip函数的问题的启发:
为什么在IEnumerable接口上没有ForEach扩展方法?或在任何地方吗?唯一获得ForEach方法的类是List<>。有什么原因吗,也许是性能?
当前回答
@Coincoin
foreach扩展方法的真正功能包括Action<>的可重用性,而无需向代码添加不必要的方法。假设您有10个列表,并且您希望对它们执行相同的逻辑,而对应的函数不适合您的类并且不能重用。您可以将所有逻辑保存在一个地方,而不是使用十个for循环,或者使用一个显然不属于helper的通用函数(Action<>。所以,很多行被替换成
Action<blah,blah> f = { foo };
List1.ForEach(p => f(p))
List2.ForEach(p => f(p))
等等……
逻辑是在一个地方,你没有污染你的课。
其他回答
你可以这样写扩展方法:
// 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#库有很大的不同;不熟悉您的扩展方法的读者将不知道如何理解您的代码。
当你想要返回一些东西时,你可以使用select。 如果不需要,可以先使用ToList,因为您可能不想修改集合中的任何内容。
@Coincoin
foreach扩展方法的真正功能包括Action<>的可重用性,而无需向代码添加不必要的方法。假设您有10个列表,并且您希望对它们执行相同的逻辑,而对应的函数不适合您的类并且不能重用。您可以将所有逻辑保存在一个地方,而不是使用十个for循环,或者使用一个显然不属于helper的通用函数(Action<>。所以,很多行被替换成
Action<blah,blah> f = { foo };
List1.ForEach(p => f(p))
List2.ForEach(p => f(p))
等等……
逻辑是在一个地方,你没有污染你的课。
我自己也一直在想,这就是为什么我总是带着这个:
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);
}
}
不错的扩展方法。
请注意,MoreLINQ NuGet提供了您正在寻找的ForEach扩展方法(以及执行委托并产生结果的Pipe方法)。看到的:
https://www.nuget.org/packages/morelinq https://code.google.com/p/morelinq/wiki/OperatorsOverview