我有一些名单:
List<int> list = new List<int> { 1, 2, 3, 4, 5 };
我想对列表中的元素应用一些转换。我可以通过两种方式做到这一点:
List<int> list1 = list.Select(x => 2 * x).ToList();
List<int> list2 = list.ConvertAll(x => 2 * x).ToList();
这两种方式有什么区别?
答案 0 :(得分:106)
Select
是一种LINQ扩展方法,适用于所有IEnumerable<T>
个对象,而ConvertAll
仅由List<T>
实现。自.NET 2.0起存在ConvertAll
方法,而LINQ与3.5一起引入。
你应该支持Select
而不是ConvertAll
因为它适用于任何类型的列表,但它们基本上都是这样做的。
答案 1 :(得分:77)
ConvertAll
不是扩展名,它是列表类中的一个方法。您不必在结果上调用ToList
,因为它已经是一个列表:
List<int> list2 = list.ConvertAll(x => 2 * x);
因此,区别在于ConvertAll
方法只能在列表中使用,并返回一个列表。 Select
方法可用于实现IEnumerable<T>
接口的任何集合,并返回IEnumerable<T>
。
此外,他们以不同的方式进行处理,因此他们在不同的情况下有自己的优势。 ConvertAll
方法在列表中运行并一次创建一个新列表,而Select
方法使用延迟执行并仅根据需要处理项目。如果您不需要所有项目,则Select
方法更有效。另一方面,一旦ConvertAll
返回列表,您就不需要保留原始列表。
答案 2 :(得分:1)
我知道这有点迟了但我还是补充说因为这可能会对其他人有所帮助。
在EntityFramework查询表达式中使用它时,建议不要使用ConvertAll(),因为它会计算表达式而不是将其作为表达式保留以供将来使用。这会严重降低数据库查询执行性能,因为在评估最终表达式之前必须进行多次调用。
答案 3 :(得分:0)
第一个答案不应是被接受的答案。我曾是2007 C#Microsoft MVP。
与接受的响应相反,ConvertAll
比Select
和ToList()
的组合要有效得多。
首先,ConvertAll
严格更快,并且它使用最少的内存来做到这一点。与Array.ConvertAll与Select和ToArray相同。对于更大长度的数组或一个循环中的许多调用,这将更为明显。
1)ConvertAll
知道最终列表的大小,并避免了重新分配基本数组。 ToList
()将多次调整数组大小。
2)ToList
将使接口IEnumerable<>
的调用变慢,而ConvertAll
将遍历基础数组,而无需进行额外的调用或范围检查。
3)选择将创建一个额外的IEnumerable<T>
对象。