关于c#:为什么只有List< T>上的ForEach方法?

Why is ForEach Method only on the List<T> collection?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Why is there not a ForEach extension method on the IEnumerable interface?

首先,让我指定我引用的是List方法,而不是c关键字。对于在List集合上使用foreach方法,但没有其他集合/可枚举类型,特别是IEnumerable集合,微软的理由是什么?

前几天我刚刚发现了这个方法,并且发现它对于替换传统的for each循环是非常好的语法,传统的foreach循环只对每个对象执行一到两行方法。

似乎创建一个执行相同函数的扩展方法是非常简单的。我想我在研究微软为什么做出这个决定,并且基于这个,如果我只需要做一个扩展方法的话。


埃里克·利珀特已经多次回答这个问题,包括在他的博客上。

他的回答是,ForEach()是一种明确用于其副作用的东西,而linq主要是用来定义序列上的投影和操作的无副作用的API。

在并行循环等用途之外,函数ForEach语法在表达能力方面没有增加太多,而且由于委托调用,它的效率比常规ForEach循环稍低。

如果你真的,真的想要一个ForEachIEnumerable,写一个并不难:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static class ForEachExtension
{
    public static void ForEach<T>( this IEnumerable<T> seq, Action<T> action )
    {
        foreach( var item in seq )
            action( item );
    }

    // Here's a lazy, streaming version:
    public static IEnumerable<T> ForEachLazy<T>( this IEnumerable<T> seq, Action<T> action )
    {
        foreach( var item in seq )
        {
            action( item );
            yield return item;
        }
    }
}


从帮助设计编译器的人那里读到答案。http://blogs.msdn.com/ericlippet/archive/2009/05/18/foreach-vs-foreach.aspx


在扩展方法之前就写了这个-它被添加到.NET 2.0中。当时,没有办法将它作为任何可枚举的扩展添加——它必须是接口的一部分(我同意这不一定适合,因为可枚举的长度可以是无限长的,这很糟糕)。

我相信,当C 3发布时,他们可能会觉得Linq通过Select提供了一个简单的替代方案,同时对副作用更加清楚。埃里克·利珀特的博客文章描述了副作用,以及为什么你会更详细地使用前臂和前臂的基本原理。


陈瑞蒙(埃里克·冈纳森)的回答是:

Every feature starts off at -100 points.

基本上,必须有人来写它,这样做会使时间从其他特性上消失。因为您可以自己创建ForEach(),所以它永远不会优先于其他不那么简单的功能。

加上ForEach()早于扩展方法。