3

I just found a couple of c# code refactoring examples on the internet, and stumbled upon this particular piece of code.

Can anyone explain to me, why Method2() would be better than Method1()?

Method #1 - Doing multiple iterations on IEnumerable<string>

public void Method1()
{
    IEnumerable<string> names = GetNames();

    foreach (var name in names)
    {
        Console.WriteLine("Found " + name);
    }

    var allnames = new StringBuilder();

    foreach (var name in names)
    {
        allnames.Append(name + " ");
    }
}

Method #2 - Doing multiple iterations on List<string>

public void Method2()
{
    IEnumerable<string> names = GetNames();

    var enumerable = names as List<string> ?? names.ToList();

    foreach (var name in enumerable)
    {
        Console.WriteLine("Found " + name);
    }

    var allnames = new StringBuilder();

    foreach (var name in enumerable)
    {
        allnames.Append(name + " ");
    }
}
Patrick D'Souza
  • 3,491
  • 2
  • 22
  • 39
T Jensen
  • 85
  • 1
  • 6

3 Answers3

4

Because IEnumerable may do lazy iteration. In which case the iteration code will run twice.

For example, if GetNames is actually communicating with a DB then iterating over the returned IEnumerable may perform the actual SQL query. In which case in Method 1 you're going to perform that task twice.

In method 2 the call to ToList causes evaluation of the IEnumerable only once and so your SQL query would only run once.

Because you don't always know what is actually behind an IEnumerable it's often seen as best practice to force enumeration only once.

Nick
  • 25,026
  • 7
  • 51
  • 83
  • The example was only on c# objects. No SQL connections involved, which caused my doubt of the "power" of the refactoring. But as you say, it is probably seen as a best practice since you don't know what's behind the IEnumerable. – T Jensen May 30 '13 at 18:21
0

Both method are good at what it does. The only differentiating factor is why we should use one or the other. In case of second method, the .ToList() call eagerly evaluate the expression, which prepare the IEnumerable collection. And in the first method, it only evaluate the expression when CLR execute following code block. As i said, it depend on how you want to get ahead.

foreach (var name in names)
S.N
  • 4,910
  • 5
  • 31
  • 51
0

Method 2 is better because there are possible multiple enumeration of IEnumerable.

Palak.Maheria
  • 1,497
  • 2
  • 15
  • 32