LINQ 产生所有元素
LINQ yield all elements
当我想得到一个 IEnumerable 到 eagrly materialize/yield 它的所有结果时,我通常使用 ToList()
像这样:
var myList= new List<int>();
IEnumerable<int> myXs = myList.Select(item => item.x).ToList();
我通常在锁定返回 Linq 查询结果的方法时这样做。
在这种情况下,我实际上对集合变成列表不感兴趣,而且我通常不想知道它的类型。我只是使用 ToList() 因为它的副作用 - 产生所有元素。
例如,如果我将类型从 List 更改为 Array,我还必须记住将 ToList() 更改为 ToArray() 或遭受一些性能影响。
我可以 foreach( var e in myList ) { }
但我不确定这是否会在某个时候得到优化?
我正在寻找类似 myList.Select(item => item.x).yield()
的内容
最好的方法是什么?有没有一种方法可以简单地告诉 Linq 结果产生比 ToList
更好的所有元素?
如果重点只是练习列表,不想构造或分配任何类型的数组,您可以使用 Last()
,它将简单地遍历所有元素,直到它得到到最后一个(参见 source)。
如果您真的对结果感兴趣,在大多数情况下您应该 use ToList() 而不要想太多。
如果您想稍后检索结果,就无法避免分配某种存储空间。没有没有具体类型的神奇 IEnumerable<T>
容器;你必须选择一个,ToList()
是最明显的选择,开销很低。
如果您不想等待它完成,请不要忘记 ToListAsync()。
仅供参考,因为这可能就是问题所在
您不必在一行中编写 LINQ 操作,您可以进一步扩展它:
例如:
var myList = new List<T>();
var result = myList.Select(x => x.Foo).Where(x => x.City == "Vienna").Where(x => x.Big == true).ToList();
可以重写为:
var myList = new List<T>();
//get an IEnumerable<Foo>
var foos = myList.Select(x => x.Foo);
//get an IEnumerable<Foo> which is filtered by the City Vienna
var foosByCity = foos.Where(x => x.City == "Vienna");
//get an IEnumerable<Foo> which is futher filtered by Big == true
var foosByCityByBig = foosByCity.Where(x => x.Big == true);
//now you could call to list on the last IEnumerable, but you dont have to
var result = foosByCityByBig.ToList();
所以无论你的真正目标是什么,也许你可以改变你的路线
var myList= new List<int>();
IEnumerable<int> myXs = myList.Select(item => item.x).ToList();
为此:
var myList= new List<int>();
IEnumerable<int> myXs = myList.Select(item => item.x);
并继续 myXs
作为 IEnumerable<int>
的工作。
当我想得到一个 IEnumerable 到 eagrly materialize/yield 它的所有结果时,我通常使用 ToList()
像这样:
var myList= new List<int>();
IEnumerable<int> myXs = myList.Select(item => item.x).ToList();
我通常在锁定返回 Linq 查询结果的方法时这样做。
在这种情况下,我实际上对集合变成列表不感兴趣,而且我通常不想知道它的类型。我只是使用 ToList() 因为它的副作用 - 产生所有元素。
例如,如果我将类型从 List 更改为 Array,我还必须记住将 ToList() 更改为 ToArray() 或遭受一些性能影响。
我可以 foreach( var e in myList ) { }
但我不确定这是否会在某个时候得到优化?
我正在寻找类似 myList.Select(item => item.x).yield()
最好的方法是什么?有没有一种方法可以简单地告诉 Linq 结果产生比 ToList
更好的所有元素?
如果重点只是练习列表,不想构造或分配任何类型的数组,您可以使用 Last()
,它将简单地遍历所有元素,直到它得到到最后一个(参见 source)。
如果您真的对结果感兴趣,在大多数情况下您应该 use ToList() 而不要想太多。
如果您想稍后检索结果,就无法避免分配某种存储空间。没有没有具体类型的神奇 IEnumerable<T>
容器;你必须选择一个,ToList()
是最明显的选择,开销很低。
如果您不想等待它完成,请不要忘记 ToListAsync()。
仅供参考,因为这可能就是问题所在
您不必在一行中编写 LINQ 操作,您可以进一步扩展它:
例如:
var myList = new List<T>();
var result = myList.Select(x => x.Foo).Where(x => x.City == "Vienna").Where(x => x.Big == true).ToList();
可以重写为:
var myList = new List<T>();
//get an IEnumerable<Foo>
var foos = myList.Select(x => x.Foo);
//get an IEnumerable<Foo> which is filtered by the City Vienna
var foosByCity = foos.Where(x => x.City == "Vienna");
//get an IEnumerable<Foo> which is futher filtered by Big == true
var foosByCityByBig = foosByCity.Where(x => x.Big == true);
//now you could call to list on the last IEnumerable, but you dont have to
var result = foosByCityByBig.ToList();
所以无论你的真正目标是什么,也许你可以改变你的路线
var myList= new List<int>();
IEnumerable<int> myXs = myList.Select(item => item.x).ToList();
为此:
var myList= new List<int>();
IEnumerable<int> myXs = myList.Select(item => item.x);
并继续 myXs
作为 IEnumerable<int>
的工作。