2011-10-20 48 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