我想在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

我想在LINQ中执行以下等效操作,但我无法确定如何执行:

正如其他人在国内外指出的,LINQ和IEnumerable方法预计不会产生副作用。

你真的想对IEnumerable中的每个项目“做点什么”吗?那么foreach是最好的选择。当这里出现副作用时,人们并不感到惊讶。

foreach (var i in items) i.DoStuff();

我打赌你不想有副作用

然而,根据我的经验,通常不需要副作用。通常情况下,有一个简单的LINQ查询等待被发现,并伴随着Jon Skeet、Eric Lippert或Marc Gravell的StackOverflow.com回答,解释如何做您想要的事情!

一些示例

如果您实际上只是在聚合(累积)一些值,那么应该考虑聚合扩展方法。

items.Aggregate(initial, (acc, x) => ComputeAccumulatedValue(acc, x));

也许您想从现有值创建一个新的IEnumerable。

items.Select(x => Transform(x));

或者你想创建一个查找表:

items.ToLookup(x, x => GetTheKey(x))

可能性的列表(双关语并非完全有意)还在继续。

又一个ForEach示例

public static IList<AddressEntry> MapToDomain(IList<AddressModel> addresses)
{
    var workingAddresses = new List<AddressEntry>();

    addresses.Select(a => a).ToList().ForEach(a => workingAddresses.Add(AddressModelMapper.MapToDomain(a)));

    return workingAddresses;
}

根据PLINQ(从.Net 4.0开始提供),您可以执行

IEnumerable<T>.AsParallel().ForAll() 

在IEnumerable上执行并行foreach循环。

您可以使用FirstOrDefault()扩展,该扩展可用于IEnumerable<T>。通过从谓词返回false,它将为每个元素运行,但不会在意它实际上没有找到匹配项。这将避免ToList()开销。

IEnumerable<Item> items = GetItems();
items.FirstOrDefault(i => { i.DoStuff(); return false; });

很多人都提到过,但我不得不把它写下来。这不是最清晰/最可读吗?

IEnumerable<Item> items = GetItems();
foreach (var item in items) item.DoStuff();

简短而简单(st)。