Manvinder
Manvinder

Reputation: 4591

Linq ForEach vs All Performance review

For most of the time I am using All(and returns true) instead of ForEach. Is it a good practice to use ALL instead of ForEach all the time(in case of IEnumerable), I understand All could be run on IEnumerable whereas foreach runs only on list

  var wells = GlobalDataModel.WellList.Where(u => u.RefProjectName == project.OldProjectName);
  if (wells.Any())
        {
            wells.All(u =>
            {
                u.RefProjectName = project.ProjectName;
                return true;
            });
        }

   var wellsList = GlobalDataModel.WellList.Where(u => u.RefProjectName == project.OldProjectName).ToList();
   wellsList.ForEach(u => u.RefProjectName = project.ProjectName);

Upvotes: 0

Views: 645

Answers (2)

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73502

Nope, You're abusing the All method. Take a look at documentation

Determines whether all elements of a sequence satisfy a condition.

It should be used to determine all elements are true/false based on some condition, It is not meant to used to produce side effects.

List.ForEach is meant to be used for side effects. You may use it if you already have List<T> upfront. Calling ToList and creating new List just for the sake of List.ForEach is not worth. It adds another O(n) operation.

In short don't use All for side effects, List.ForEach is barely acceptable when you have list already. Recommended way is use loop of your choice, nothing can be better than that.

Ericlippert has something to say about ForEach, note that it is removed in ModernUI apps, may be removed in desktop version of .net too.

Upvotes: 4

sinelaw
sinelaw

Reputation: 16563

If you're checking whether all elements satisfy some condition, use All.

But, if you need to perform some operation on each element, don't use All or any other LINQ predicate (Where, Select, Any, etc.), as they are meant to be used in a purely functional way. You can iterate over the elements using a foreach .. in loop or if you prefer with the List<T>.ForEach method. However as you mention it is part of List<T> and makes your code slightly harder to change (e.g. from list to another enumerable).

See here for a discussion about the "right way" to use LINQ.


For example, you can write your code like this:

foreach (var u in GlobalDataModel.WellList
                                 .Where(u => u.RefProjectName == project.OldProjectName)) 
{
    u.RefProjectName = project.ProjectName;
}

It's more obvious that side effects are being done. Also, this will only iterate once over the sequence, skipping the elements that don't satisfy the condition.

Upvotes: 2

Related Questions