我想在LINQ中执行以下等效操作,但我无法确定如何执行:
IEnumerable<Item> items = GetItems();
items.ForEach(i => i.DoStuff());
真正的语法是什么?
我想在LINQ中执行以下等效操作,但我无法确定如何执行:
IEnumerable<Item> items = GetItems();
items.ForEach(i => i.DoStuff());
真正的语法是什么?
当前回答
MoreLinq有IEnumerable<T>.ForEach和许多其他有用的扩展。仅为ForEach使用依赖关系可能不值得,但其中有很多有用的东西。
https://www.nuget.org/packages/morelinq/
https://github.com/morelinq/MoreLINQ
其他回答
IEnumerable没有ForEach扩展;仅适用于列表<T>。所以你可以
items.ToList().ForEach(i => i.DoStuff());
或者,编写自己的ForEach扩展方法:
public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
foreach(T item in enumeration)
{
action(item);
}
}
正如许多答案已经指出的那样,您可以自己轻松地添加这样的扩展方法。然而,如果您不想这样做,尽管我不知道BCL中有什么类似的内容,但如果您已经引用了Reactive Extension(如果没有,您应该有),System命名空间中仍然有一个选项:
using System.Reactive.Linq;
items.ToObservable().Subscribe(i => i.DoStuff());
虽然方法名称有点不同,但最终结果正是您所希望的。
Fredrik提供了解决方案,但可能值得考虑一下为什么这不在框架中。我认为,LINQ查询运算符应该是无副作用的,符合合理的功能性世界观。很明显,ForEach恰恰相反——一个纯粹基于副作用的构造。
这并不是说这是一件坏事——只是想想这个决定背后的哲学原因。
您可以使用FirstOrDefault()扩展,该扩展可用于IEnumerable<T>。通过从谓词返回false,它将为每个元素运行,但不会在意它实际上没有找到匹配项。这将避免ToList()开销。
IEnumerable<Item> items = GetItems();
items.FirstOrDefault(i => { i.DoStuff(); return false; });
现在我们可以选择。。。
ParallelOptions parallelOptions = new ParallelOptions();
parallelOptions.MaxDegreeOfParallelism = 4;
#if DEBUG
parallelOptions.MaxDegreeOfParallelism = 1;
#endif
Parallel.ForEach(bookIdList, parallelOptions, bookID => UpdateStockCount(bookID));
当然,这打开了一个全新的线虫罐头。
ps(对不起,字体是系统决定的)