C#中Select和ConvertAll之间的区别

And*_*hin 110 .net c# list

我有一些清单:

List<int> list = new List<int> { 1, 2, 3, 4, 5 };
Run Code Online (Sandbox Code Playgroud)

我想对我列表中的元素应用一些转换.我可以通过两种方式做到这一点:

List<int> list1 = list.Select(x => 2 * x).ToList();
List<int> list2 = list.ConvertAll(x => 2 * x).ToList();
Run Code Online (Sandbox Code Playgroud)

这两种方式有什么区别?

Oli*_*ppi 112

Select是一个LINQ扩展方法,适用于所有IEnumerable<T>对象,而ConvertAll只能由List<T>.该ConvertAll方法自.NET 2.0起存在,而LINQ与3.5一起引入.

你应该赞成Select,ConvertAll因为它适用于任何类型的列表,但他们基本上做同样的事情.

  • 表演怎么样?如果我有一个List,使用ConvertAll或Select会更高效吗? (6认同)
  • ConvertAll 和 Select 之间的区别是 ConvertAll 会预先分配列表的大小。对于大型序列,这将导致性能差异。因此,如果性能是您的目标,请使用 ConvertAll。如果性能不是问题,请使用 Select,因为它在语言中更惯用,并告诉未来的读者性能不是问题。 (6认同)
  • 你无法比较`Select`和`ConvertAll`.前者选择序列中的每个项目,您可以随意使用它做任何事情.后者有一个明确的意图:将此项目转换为其他内容. (3认同)
  • 有趣的是,List&lt;T&gt; 类包含几个在 LINQ 中几乎完全匹配的方法。存在 -&gt; 任意、查找 -&gt; 第一个、FindAll -&gt; 其中、FindLast -&gt; 最后一个、TrueForAll -&gt; 全部 (3认同)

Guf*_*ffa 80

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

List<int> list2 = list.ConvertAll(x => 2 * x);
Run Code Online (Sandbox Code Playgroud)

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

而且,他们以不同的方式进行处理,因此他们在不同的情况下有自己的优势.该ConvertAll方法在列表中运行并一次创建一个新列表,而该Select方法使用延迟执行,只在您需要时处理这些项.如果您不需要所有项目,则该Select方法更有效.另一方面,一旦ConvertAll返回列表,您不需要保留原始列表.

  • @ user2864740:是的,如果源严格地是内存中的列表,则为true.如果从例如文件中读取,则需要保持文件打开,直到您处理了"Select"的结果. (8认同)

小智 7

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

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

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

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

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

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

  • 这不再正确/准确。请参阅https://github.com/dotnet/runtime/issues/38418#issuecomment-706803864 (12认同)
  • @Graham Roslynator 确实建议进行此更改,我在 VS2022 (6认同)
  • 作为旁注 VS2019 建议 ConvertAll 替换 Select + ToList (3认同)
  • 我为 .NET 6 所做的基准测试表明,ConvertAll 的性能优于 Select https://gist.github.com/VaclavElias/b3b521205415d6ae1cf3d5ca9d9cad10。我建议对您的场景进行相同的测试:) (2认同)