C#中的Select和ConvertAll之间的区别


117

我有一些清单:

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();

这两种方式有什么区别?


16
在ConvertAll()之后,您不需要.ToList()。
Gleno

从来没有听说过ConvertAll,今天知道了一些新东西
Amit Bisht

Answers:


117

Select是LINQ扩展方法,适用于所有IEnumerable<T>对象,但ConvertAll仅由实现List<T>。该ConvertAll方法从.NET 2.0开始存在,而LINQ在3.5中引入。

您应该偏爱它SelectConvertAll因为它适用于任何类型的列表,但它们的作用基本上相同。


7
那表演呢?如果我有一个列表,使用ConvertAll或Select是否更有性能?
尼古拉斯

@Nicolas:总执行时间大约相同,但是它们的处理方式不同,因此适合不同的情况。我在回答中添加了一些相关内容。
Guffa

3
您无法比较SelectConvertAll。前者会选择序列中的每个项目,您可以随意使用它进行任何操作。后者有明确的意图:将此项转换为其他内容。
蒂姆·施密特

1
有趣的是,List <T>类包含几种在LINQ中几乎完全匹配的方法。存在->任何,查找->首先,查找全部->位置,查找最后->最后,TrueForAll->全部
Mikal Schacht Jensen

ConvertAll和Select之间的区别是ConvertAll将事先分配列表的大小。对于较大的序列,这将导致性能差异。因此,如果性能是您的目标,请使用ConvertAll。如果不关心性能,请使用“选择”,因为它在语言中更惯用,并告诉将来的读者性能不是问题。
Durdsoft

82

ConvertAll不是扩展名,而是列表类中的方法。您不必调用ToList结果,因为它已经是一个列表:

List<int> list2 = list.ConvertAll(x => 2 * x);

因此,不同之处在于该ConvertAll方法只能在列表上使用,并且它返回一个列表。该Select方法可用于实现该IEnumerable<T>接口的任何集合,并返回IEnumerable<T>

此外,它们的处理方式也不同,因此它们在不同情况下具有优势。该ConvertAll方法遍历列表并一次性创建一个新列表,而该Select方法使用延迟执行,仅在需要时处理项目。如果不需要所有项目,则该Select方法更有效。另一方面,ConvertAll返回列表后,您无需保留原始列表。


可以说,人们永远不必“保留原始列表”:它将根据GC的需要完成。
user2864740 '16

8
@ user2864740:是的,如果源严格是内存中的列表,则为true。如果从例如文件中读取文件,则需要保持文件打开状态,直到从中处理了结果Select
古法'16

19

第一个答案不应是被接受的答案。我曾经是2007 C#Microsoft MVP。

与此相反的接受响应,ConvertAll比的组合更有效SelectToList()

首先,ConvertAll严格来说是更快的,并且它使用最少的内存来做到这一点。与Array.ConvertAll与Select和ToArray相同。对于更大长度的数组或循环中的许多调用,这将更加明显。

1)ConvertAll知道最终列表的大小,并避免重新分配基本数组。ToList()将继续调整数组大小。

2)ToList将使接口IEnumerable<>调用变慢,而ConvertAll将循环遍历基础数组而无需额外的调用或范围检查。

3)选择将创建一个额外的IEnumerable<T>对象。


1

我知道这有点晚了,但我仍然添加,因为这将来可能对其他人有用。

在EntityFramework查询表达式中使用它时,不建议使用ConvertAll(),因为它会评估表达式,而不是将其保留为表达式以供将来使用。这将严重降低数据库查询的执行性能,因为在评估最终表达式之前必须进行多次调用。


9
不完全的。正如Guffa 在这个答案中指出的,ConvertAll 是一种方法List<T>。通过你的时间名单,你已经评估了表达。但是您是对的-如果您不想对所有内容都进行评估,Select则更可取。
李慧夏
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.