可能重复:
Why is there not a ForEach extension method on the IEnumerable interface?
你好,
我的问题是为什么Foreach扩展方法是在List而不是IEnumreable上定义的。我读过Eric Lippert的article,但问题是,如果有这样的方法,那么为什么它不适用于List?
答案 0 :(得分:12)
List<T>.ForEach()
不是扩展方法。这只是List<T>
上的一种方法。
LINQ中不可用的一个主要原因(即Enumerable
)是LINQ查询应该没有副作用(因此你可以,例如,多次执行查询并且在不改变它们的情况下获得相同的结果),这使得它们非常可组合。接受委托的所有LINQ操作都是Func
;他们都不接受Action
代表。
答案 1 :(得分:6)
这是我在Microsoft Connect网站上发布的一个错误,微软已经在即将发布的.NET版中修复了它,如下面的链接所示。
List.ForEach allows enumeration over modified version of List
这可能与答案没有直接关系,但它对我刚刚发现的内容非常有趣。
ForEach,删除(工作)
List<int> list = new List<int>(){ 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的完全一半实现的功能,因为如果修改了集合,枚举将总是导致问题。
尽管存在争论,我仍然认为ForEach不应该允许修改,它纯粹用于枚举,它的foreach(x中的var项)语法或x.ForEach(x =&gt; {没有区别})语法。
我不同意Eric,我只是简单地看到BCL团队已经在IEnumerable和list.ForEach上实现了这个功能。
“为什么”是完全主观的,例如,Silverlight添加了复杂的散列算法,并且MD5落后于其他地方我们广泛使用MD5的其他地方。更多的是需要多少东西以及选择是否将其包含在框架中的人。
在IEnumerable中没有ForEach没有任何逻辑或哲学原因。有很多这样的缺点我认为.NET会随着时间的推移而改进。
答案 2 :(得分:1)
应该避免使用LINQ变异状态并且不鼓励,LINQ的重点是查询和转换数据,但没有到位突变 - 你失去了LINQ功能方法的许多好处(即没有副作用) ,如果你改变了状态,那么相同的输入产生相同的输出。
Linq在正常ForEach()
循环上提供foreach
扩展方法没有任何好处,除了它可以帮助你改变状态 - 因此它没有实现(至少我对它的看法) ,带上一粒盐。)
答案 3 :(得分:0)
'为什么'超出了我的范围;我没有制作C#。但是,它是有道理的,因为它将完全枚举您的集合,而大多数LINQ运算符被懒惰地评估。