【问题标题】:Difference between Select and ConvertAll in C#C#中Select和ConvertAll的区别
【发布时间】:2010-12-07 00:11:25
【问题描述】:

我有一些清单:

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

这两种方式有什么区别?

【问题讨论】:

  • 在 ConvertAll() 之后不需要 .ToList()。
  • 从未听说过 ConvertAll,今天了解了一些新东西

标签: c# .net list


【解决方案1】:

Select 是一种 LINQ 扩展方法,适用于所有 IEnumerable&lt;T&gt; 对象,而 ConvertAll 仅由 List&lt;T&gt; 实现。 ConvertAll 方法自 .NET 2.0 起就存在,而 LINQ 是在 3.5 中引入的。

您应该更喜欢 Select 而不是 ConvertAll,因为它适用于任何类型的列表,但它们的作用基本相同。

【讨论】:

  • 表演怎么样?如果我有一个列表,使用 ConvertAll 或 Select 是否更高效?
  • @Nicolas:总执行时间大致相同,但它们的处理方式不同,因此适合不同的情况。我在回答中添加了一些关于它的内容。
  • 您无法比较 SelectConvertAll。前者选择序列中的每个项目,您可以随意使用它。后者有一个明确的意图:将这个项目转换成别的东西。
  • 有趣的是,List 类包含几个在 LINQ 中几乎完全匹配的方法。 Exists -> Any, Find -> First, FindAll -> Where, FindLast -> Last, TrueForAll -> All
  • ConvertAll 和 Select 的区别在于 ConvertAll 会预先分配列表的大小。对于大序列,这将产生性能差异。因此,如果性能是您的目标,请使用 ConvertAll。如果性能不是问题,请使用 Select,因为它在语言中更惯用,并告诉未来的读者性能不是问题。
【解决方案2】:

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

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

所以,区别在于ConvertAll 方法只能用于列表,它返回一个列表。 Select 方法可以用于任何实现了IEnumerable&lt;T&gt; 接口的集合,它返回一个IEnumerable&lt;T&gt;

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

【讨论】:

  • 可以说,永远不必“保留原始列表”:它将根据 GC 的需要完成。
  • @user2864740:是的,如果源严格来说是内存中的一个列表,那就是真的。如果它是从例如一个文件中读取的,那么您需要保持文件打开,直到您处理了来自 Select 的结果。
【解决方案3】:

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

与接受的响应相比,ConvertAllSelectToList() 的组合更有效。

首先,ConvertAll 绝对更快,并且它使用最少的内存量来执行此操作。与 Array.ConvertAll 与 Select 和 ToArray 相同。对于更大长度的数组或循环中的许多调用,这一点会更加明显。

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

2) ToList 将进行较慢的接口 IEnumerable&lt;&gt; 调用,而 ConvertAll 将循环遍历底层数组,无需额外调用或范围检查。

3) Select 将创建一个额外的IEnumerable&lt;T&gt; 对象。

【讨论】:

【解决方案4】:

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

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

【讨论】:

  • 不完全。正如 Guffa 指出的 in this answerConvertAll is a method on List&lt;T&gt;。当您拥有列表时,您已经评估了您的表达式。但你是对的 - 如果你不想评估所有,Select 更可取。
猜你喜欢
  • 1970-01-01
  • 2018-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-22
  • 1970-01-01
相关资源
最近更新 更多