受到另一个关于缺失Zip函数的问题的启发:

为什么在IEnumerable接口上没有ForEach扩展方法?或在任何地方吗?唯一获得ForEach方法的类是List<>。有什么原因吗,也许是性能?


当前回答

请注意,MoreLINQ NuGet提供了您正在寻找的ForEach扩展方法(以及执行委托并产生结果的Pipe方法)。看到的:

https://www.nuget.org/packages/morelinq https://code.google.com/p/morelinq/wiki/OperatorsOverview

其他回答

一种解决方法是编写. tolist()。ForEach(x =>…)

pros

易于理解——读者只需要知道c#附带了什么,而不需要知道任何额外的扩展方法。

语法干扰非常温和(只添加了一点无关的代码)。

通常不需要额外的内存,因为本机. foreach()必须实现整个集合。

cons

操作顺序并不理想。我宁愿实现一个元素,然后付诸行动,然后重复。这段代码首先实现所有元素,然后依次对它们进行操作。

如果意识到列表抛出异常,则永远无法对单个元素进行操作。

如果枚举数是无限的(就像自然数一样),那么你就不走运了。

当你想要返回一些东西时,你可以使用select。 如果不需要,可以先使用ToList,因为您可能不想修改集合中的任何内容。

大多数LINQ扩展方法都返回结果。ForEach不符合这个模式,因为它什么也不返回。

ForEach方法在LINQ之前添加。如果您添加ForEach扩展,由于扩展方法的约束,它将永远不会被用于List实例。我认为没有添加的原因是为了不干扰现有的。

但是,如果您真的错过了这个漂亮的小函数,您可以推出自己的版本

public static void ForEach<T>(
    this IEnumerable<T> source,
    Action<T> action)
{
    foreach (T element in source) 
        action(element);
}

这里的讨论给出了答案:

实际上,我所看到的具体讨论确实取决于功能的纯洁性。在一个表达式中,经常会有关于没有副作用的假设。使用ForEach是特别吸引副作用,而不仅仅是忍受它们。——基思·法默(合伙人)

基本上,这个决定是为了保持扩展方法在功能上的“纯粹”。ForEach在使用Enumerable扩展方法时会产生副作用,这不是目的。