我知道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是不好的,因为这会导致从数据库中取两次数据。但是我在内存列表中并不完全确定。如果可以,我会删除这个问题;-)
答案 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();
答案 3 :(得分:0)
将“过滤”列表更加聪明(也就是使用var并在最后添加ToList())
是的,特别是在Linq-To-Entities等方面。
使用linq返回IEnumerable
允许执行不同的操作。当您将ToList()
追加到最后时,您的列表会立即返回。
请参阅http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx