为什么ForEach Linq扩展列表而不是IEnumerable

可能重复:
为什么IEnumerable接口上没有ForEach扩展方法?

你好,

我的问题是为什么Foreach扩展方法是在List而不是IEnumreable上定义的。 我已经阅读了Eric Lippert的文章,但重点是,如果有这样的方法比为什么它的列表那么糟糕?

List.ForEach()不是扩展方法。 它只是List上的一个方法。

在LINQ中不可用的主要原因之一(即Enumerable )是LINQ查询应该没有副作用(因此您可以,例如,多次执行查询并获得相同的结果而不更改他们),这使他们非常容易组合。 接受委托的所有LINQ操作都是针对Func ; 他们都不接受Action代表。

这是我在Microsoft Connect网站上发布的一个错误,微软已经在即将发布的.NET版中修复了它,如下面的链接中所述。

List.ForEach允许枚举修改版本的List

这可能与答案没有直接关系,但它对我刚刚发现的内容非常有趣。

ForEach,删除(工作)

 List list = new List(){ 1, 2, 3, 4, 5, 6}; list.ForEach(x => { Console.WriteLine(x); list.Remove(x); }); 

foreach,删除(崩溃)

 // throws exception foreach (var x in list) { Console.WriteLine(x); list.Remove(x); } 

ForEach,插入(…)

 // goes in infinite loop... list.ForEach(x => { list.Add(1); }); 

foreach,insert(crashes)

 // throws exception foreach (var x in list) { Console.WriteLine(x); list.Add(x); } 

所以在这里谈论可变性或不同的混淆层等的任何人,我认为它是Visual Team完全一半实现的function,因为如果修改了集合,枚举将总是导致问题。

尽管存在争论,我仍然看不出ForEach应该允许修改的原因,它纯粹用于枚举,并且它的foreach(x中的var项)语法或x.ForEach(x => {})语法没有区别。

我不同意Eric,我只是简单地看到BCL团队已经在IEnumerable以及list.ForEach上实现了这个function。

“为什么”是完全主观的,例如,Silverlight添加了复杂的哈希算法,并将MD5放在了我们广泛使用MD5的其他地方。 它更多的是需要多少东西,谁选择是否在框架中包含它。

在IEnumerable中没有ForEach没有任何逻辑或哲学原因。 有很多这样的缺点,我认为.NET会随着时间的推移而改进。

应该避免使用LINQ来改变状态,而不是鼓励,LINQ的重点是查询和转换数据,但没有到位突变 – 你失去了LINQfunction方法的许多好处(即没有副作用,同样的输入如果改变状态,则产生相同的输出。

Linq在正常的foreach循环中提供ForEach()扩展方法没有任何好处,除了它可以帮助你改变状态 – 因此它没有实现(至少我对它的看法,带着一点点盐) 。

‘为什么’超出了我的范围; 我没有制作C#。 但是,它是有道理的,因为它将完全枚举您的集合,而大多数LINQ运算符被懒惰地评估。