2013-05-30 70 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。