foreach循环与ForEach方法 - 差异?

时间:2015-11-02 15:13:04

标签: c# linq foreach

编辑:此问题可以标记为this question.

的副本

使用foreach循环或ForEach LINQ方法之间是否存在任何差异(性能或其他方面)?

对于上下文,这是我的一个方法的一部分:

foreach (var property in typeof(Person).GetProperties())
{
    Validate(property.Name);
}

我也可以使用此代码执行相同的任务:

typeof(Person)
    .GetProperties()
    .ToList()
    .ForEach(property => Validate(property.Name));

何时使用循环结构比使用方法链更好?

这是我使用ForEach方法的另一个例子,但可以轻松使用foreach循环和变量:

// LINQ
PrivateData.Database.Users
           .Cast<User>()
           .Where(user => user.LoginType == LoginType.WindowsUser)
           .Select(user => new { Name = user.Name, Login = user.Login })
           .ToList()
           .ForEach(result => WriteObject(result));

// Loop
var users = PrivateData.Database.Users
               .Cast<User>()
               .Where(user => user.LoginType == LoginType.WindowsUser)
               .Select(user => new { Name = user.Name, Login = user.Login });

foreach(var user in users)
{
    WriteObject(user);
}

3 个答案:

答案 0 :(得分:6)

我会推荐你​​Eric Lipperts blog "foreach" vs "ForEach"。作为C#编译器团队的前任主要开发人员,我认为他的意见很明显。

摘录:(参考.ForEach()

  

第一个原因是这样做违反了所有其他序列运算符所基于的函数式编程原则。显然调用此方法的唯一目的是引起副作用。表达式的目的是计算一个值,而不是引起副作用。声明的目的是产生副作用。这个东西的调用站点看起来很像一个表达式(但是,诚然,因为该方法是void返回的,所以表达式只能在“语句表达式”上下文中使用。)它不适合我制作唯一一个仅对其副作用有用的序列操作符。

答案 1 :(得分:-1)

循环是更好的风格,因为它是一个完全符合你想要的工具。它与语言更好地集成。例如,您可以从循环中断开。工具了解循环,他们不理解ForEach

循环对于人类来说也更容易理解。 ForEach非常罕见。

循环也更快,因为间接调用较少,委托分配较少,优化器可以在一个地方看到更多您正在做的事情。它还会保存ToList电话。您也可以通过在IEnumerable<T>上编写自定义扩展方法来保存该调用。

我认为循环在我能想到的所有情况下都是优越的。也许还有一些极端情况,ForEach方法由于某些原因会更好或更方便。

PLINQ也有一个ForAll,这是出于效率原因所必需的,因为它可以并行化。

答案 2 :(得分:-3)

在大多数情况下,这是个人偏好的问题。谈论表现:

大多数情况下,LINQ会慢一点,因为它会引入开销。如果您非常关心性能,请不要使用LINQ。使用LINQ是因为您需要更短的更易读和可维护的代码。