IEnumerable的多个枚举

时间:2011-10-20 07:39:56

标签: linq 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是不好的,因为这会导致从数据库中取两次数据。但是我在内存列表中并不完全确定。如果可以,我会删除这个问题;-)

4 个答案:

答案 0 :(得分:7)

大名单将重复两次。要检查这是否真的发生了,请将查询更改为:

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

如果你在'where t ==“Test1”部分设置一个断点,你会发现调试器在这两次迭代中都会遇到这一行。

答案 1 :(得分:1)

大名单将重复两次。如果你不想要它,你可以“实现”限制。

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

有许多答案告诉你这个。你应该更好地搜索: - )

答案 2 :(得分:0)

列表最终从IEnumrable继承检查此

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

还可以使用以下构造函数avaialble

创建IEnurable列表
public List(
    IEnumerable<T> collection
)

修改

派生过滤列表由两个方法迭代两次,但最后附加.ToList()方法。

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

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

答案 3 :(得分:0)

  

将“过滤”列表更加聪明(也就是使用var并在最后添加ToList())

是的,特别是在Linq-To-Entities等方面。

使用linq返回IEnumerable允许执行不同的操作。当您将ToList()追加到最后时,您的列表会立即返回。

请参阅http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx