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

IEnumerable<Item> items = GetItems();
items.ForEach(i => i.DoStuff());

真正的语法是什么?


当前回答

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);
    }
}

其他回答

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

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

在IEnumerable上执行并行foreach循环。

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

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

简短而简单(st)。

ForEach的目的是造成副作用。IEnumerable用于集合的惰性枚举。

当你考虑到这一点时,这个概念上的差异是非常明显的。

SomeEnumerable.ForEach(item=>DataStore.Synchronize(item));

在您对其执行“计数”或“ToList()”或其他操作之前,这不会执行。这显然不是所表达的。

您应该使用IEnumerable扩展来设置迭代链,根据其各自的源和条件定义内容。表达树是强大而高效的,但你应该学会欣赏它们的本质。而且不仅仅是为了围绕它们进行编程,以节省几个字符而忽略惰性求值。

如果您想充当枚举滚动,则应生成每个项。

public static class EnumerableExtensions
{
    public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
    {
        foreach (var item in enumeration)
        {
            action(item);
            yield return item;
        }
    }
}

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);
    }
}