list.foreach vs foreach

6

I have a list with several string , there is a difference between scrolling the list values:

This way:

ListaString.ForEach(delegate(string str)
{
    Console.WriteLine(str);
});

Or this:

foreach(string str in ListaString)
{
    Console.WriteLine(str);    
}

One is more performative than the other? Is there any significant gain?

When is it recommended to use list.foreach ? and foreach ? being List<T> .

NOTE: I know that Foreach can be used to traverse arrays and other things.   But I want to know specifically those two ways above in situations involving List<T> .

    
asked by anonymous 06.08.2015 / 14:01

2 answers

5

It has a difference, of course. The first one may be slower ( there are controversies with my identical test ) and is more confusing. So much is confusing that in the newer implementations of the class (as in WinRT, for example) it was even withdrawn since it did not bring benefits and was abused.

  • the semantics are different
  • the way in which cloistered variables are handled is different
  • It's weird to read
  • It does not allow certain constructs, such as continue and break .
  • It is difficult to debug

The first one is considered more functional, but some disagree .

In general people do not understand the peculiarities of running the loop inside the method rather than the code being written there. Better do what you understand best. If it will not bring you advantages and if you increase the chances of doing something wrong without wanting to, do not use.

And I'm talking about using with lambda and not with delegate that makes the code even larger.

The Eric Lippert wrote about this .

Note that this is different from ForEachParallel that has advantages for doing parallelism.

    
06.08.2015 / 14:24
4

Next, in terms of performance there is no significant difference, you can even see this in the following fiddle:

link

using System;
using System.Diagnostics;
using System.Linq;

public class Program
{   
    public static void Main()
    {       
        var lista = Enumerable.Range(0, 50000).Select(indice => Guid.NewGuid()).ToList();

        var relogio = new Stopwatch();
        relogio.Start();

        for (var indice = 0; indice < lista.Count; indice++)
        {
            //var reverse = Enumerable.Reverse(lista[indice].ToByteArray());
        }
        Console.WriteLine(relogio.Elapsed);

        relogio.Restart();      
        foreach (var item in lista)
        {
            //var reverse = Enumerable.Reverse(item.ToByteArray());
        }
        Console.WriteLine(relogio.Elapsed);

        relogio.Restart();      
        lista.ForEach((item) => {
            //var reverse = Enumerable.Reverse(item.ToByteArray());
        });
        Console.WriteLine(relogio.Elapsed);
    }
}

Another point I would like to mention is that Linq does not implement an extensive ForEach method for the IEnumerable Interface, we only have the List's native method.

I would also like to point out the justification given by Eric Lippert in Link :

foos.ForEach((Foo foo)=>{ statement involving foo; }); is difficult to read and debug, and can introduce other problems.

    
06.08.2015 / 14:24