2011-10-20 45 views
6

我知道IEnumerable已經在這裏討論過好幾次了,但是我找不到具體問題的答案,所以我把它作爲一個新問題提出來。IEnumerable的多次枚舉

考慮下面的代碼:

static void Main(string[] args) 
    { 

     List<string> testList = new List<string> {"Test", "Test1", "Test1"}; 
     IEnumerable<string> filtered = testList.Where(x => x == "Test1"); 

     DoSomeWork(filtered); 
     DoSomeMoreWork(filtered); 
    } 

    public static void DoSomeWork(IEnumerable<string> items) 
    { 
     foreach (var item in items) 
     { 
      Console.WriteLine("do some work"); 
     } 
    } 

    public static void DoSomeMoreWork(IEnumerable<string> items) 
    { 
     foreach (var item in items) 
     { 
      Console.WriteLine("do some more work"); 
     } 
    } 

我說得對,這會導致「testList」不僅在「過濾」兩個項目重複兩次,但實際上該項目?因此,考慮到「testList」是一個包含10000個項目的大列表,「過濾」將其減少到10個項目,將「過濾」列表(也就是使用var並在末尾附加ToList())會更加巧妙。

編輯: 這是我在這裏問過的最尷尬的問題。我知道迭代一個IQueryable會很糟糕,因爲這會導致從數據庫中兩次提取數據。但是我在內存列表中並不完全確定。我想刪除的問題,如果我能;-)使用下面的構造avaialble

回答

0

列表ultimatly從IEnumrable繼承檢查您可以創建IEnurable的列表中選擇此

public class List<T> : IList<T>, ICollection<T>, 
    IEnumerable<T>, IList, ICollection, IEnumerable 

一件事

public List(
    IEnumerable<T> collection 
) 

編輯

派生過濾列表迭代兩次的方法,但兩次nd .ToList()方法結束。

IEnumerable<string> filtered = testList.Where(x => x == "Test1").ToList(); 

http://msdn.microsoft.com/en-us/library/fkbw11z0.aspx

+0

是的,我知道。但問題是。DoSomeWork()和DoSomeMoreWork()會導致迭代大列表,還是隻迭代子集。 – Christoph

+0

@Christoph - 現在編輯回答..... –

+0

更好使用.ToArray ToList用於此用途:數組的效率更高一些,但最重要的是,它們不允許添加/刪除,避免不必要的靈活性(從而避免混淆和錯誤)。 –

1

大名單將被兩次重申。如果你不想要,你可以「實現」限制。

var filtered = testList.Where(x => x == "Test1").ToList(); 

還有很多答案告訴你這個。你應該更好的搜索:-)

7

大名單將被重申的兩倍。要檢查這真的發生更改查詢:

List<string> testList = new List<string> { "Test", "Test1", "Test1" }; 
IEnumerable<string> filtered = from t in testList 
           where t == "Test1" 
           select t; 

如果再設置上的「其中t ==‘Test1的’部分斷點,你會看到,調試器到達該線路用於迭代。

+0

啊,是的。那就對了。感謝提示! – Christoph