2013-05-30 3 views
3

Я только что нашел пару примеров рефакторинга кода C# в Интернете и наткнулся на этот конкретный фрагмент кода.Итерация с помощью IEnumerable vs List

Может кто-нибудь объяснить мне, почему Method2() будет лучше, чем Method1()?

Способ № 1 - Выполнение нескольких итераций по методу 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 + " "); 
    } 
} 

# 2 - Выполнение нескольких итераций на 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 + " "); 
    } 
} 

ответ

4

Поскольку IEnumerable может сделать ленивые итерации. В этом случае итерационный код будет работать дважды.

Например, если GetNames фактически связывается с БД, то итерация по возвращенному IEnumerable может выполнять фактический SQL-запрос. В этом случае в методе 1 вы будете выполнять эту задачу дважды.

В способе 2 вызов ToList вызывает оценку IEnumerable только один раз, и поэтому ваш SQL-запрос будет запускаться только один раз.

Поскольку вы не всегда знаете, что на самом деле стоит за IEnumerable, его часто считают лучшей практикой принудительного перечисления только один раз.

+0

Пример был только на объектах C#. Никаких подключений SQL не было, что вызвало мое сомнение в «власти» рефакторинга. Но, как вы говорите, это, вероятно, считается лучшей практикой, поскольку вы не знаете, что стоит за IEnumerable. –

0

Оба метода хороши в том, что он делает. Единственный дифференцирующий фактор - это то, почему мы должны использовать тот или иной. В случае второго метода вызов .ToList() с нетерпением оценивает выражение, которое готовит коллекцию IEnumerable. И в первом методе он оценивает только выражение, когда CLR выполняет следующий код. Как я уже сказал, это зависит от того, как вы хотите двигаться вперед.

foreach (var name in names) 
0

Метод 2 лучше, потому что существует возможность множественного перечисления IEnumerable.

Смежные вопросы