162

I have some List:

List<int> list = new List<int> { 1, 2, 3, 4, 5 };

I want to apply some transformation to elements of my list. I can do this in two ways:

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

What is the difference between these two ways?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
AndreyAkinshin
  • 18,603
  • 29
  • 96
  • 155

4 Answers4

149

Select is a LINQ extension method and works on all IEnumerable<T> objects whereas ConvertAll is implemented only by List<T>. The ConvertAll method exists since .NET 2.0 whereas LINQ was introduced with 3.5.

You should favor Select over ConvertAll as it works for any kind of list, but they do the same basically.

meJustAndrew
  • 6,011
  • 8
  • 50
  • 76
Oliver Hanappi
  • 12,046
  • 7
  • 51
  • 68
  • 19
    And what about the performances? If I have a List, is it more performant to use ConvertAll or Select? – Nicolas Dec 07 '10 at 14:28
  • @Nicolas: The total execution time is about the same, but they do the processing differently so they fit for different sitations. I added some about it in my answer. – Guffa Jul 02 '11 at 11:13
  • 5
    You can't compare `Select` and `ConvertAll`. The former selects every item in a sequence and you're free to do whatever you want with it. The latter has a clear intention: convert this item to something else. – Tim Schmelter Dec 05 '16 at 13:06
  • 2
    Interrestingly, the List class contains several methods that has almost exact matches in LINQ. Exists -> Any, Find -> First, FindAll -> Where, FindLast -> Last, TrueForAll -> All – Mikal Schacht Jensen Jun 06 '18 at 12:43
  • 11
    Difference between ConvertAll and Select is ConvertAll will allocate the size of the list before hand. For a large sequence this will make a performance difference. Thus, if performance is your aim, use ConvertAll. If performance is not a concern, use Select as it's more idiomatic in the language and tells future readers performance was not a concern. – Durdsoft Mar 20 '20 at 23:23
  • `ConvertAll` is available for arrays too, using the static `Array.ConvertAll(array, converter)`. – wezten Feb 01 '21 at 18:53
  • Since their performance is practically the same, I'd argue you should prefer calls to `ConvertAll()` since they make your intent clearer: You want to take a list/array of [thing] and turn it into a list/array of [other thing]. whereas using `Select().ToList()` can result in side effects. If that is your intent, of course. – micka190 Feb 10 '21 at 18:37
111

ConvertAll is not an extension, it's a method in the list class. You don't have to call ToList on the result as it's already a list:

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

So, the difference is that the ConvertAll method only can be used on a list, and it returns a list. The Select method can be used on any collection that implements the IEnumerable<T> interface, and it returns an IEnumerable<T>.

Also, they do the processing differently, so they have their strengths in different situations. The ConvertAll method runs through the list and creates a new list in one go, while the Select method uses lazy execution and only processes the items as you need them. If you don't need all the item, the Select method is more efficient. On the other hand, once ConvertAll has returned the list, you don't need to keep the original list.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • Arguably, one never has to "keep the original list": it will be done as needed by the GC. – user2864740 May 01 '16 at 22:55
  • 8
    @user2864740: Yes, that is true if the source is strictly a list in memory. If it's read from for example a file then you need to keep the file open until you have processed the result from the `Select`. – Guffa May 02 '16 at 00:56
43

The first answer should not be the accepted one. I am a former 2007 C# Microsoft MVP.

In contrast to the accepted response, ConvertAll is much more efficient than the combination of Select and ToList().

First of all, ConvertAll is strictly faster and it uses the minimum amount of memory to do so. Same as Array.ConvertAll vs Select and ToArray. This would be a much more evident with a larger length array or many calls within a loop.

1) ConvertAll knows the size of the final list and avoids reallocating the base array. ToList() will keep resizing the array multiple times.

2) ToList will make slower interface IEnumerable<> calls, while ConvertAll will loop through the underlying array without extra calls or range checks.

3) Select will create an extra IEnumerable<T> object.

Wesner Moise
  • 546
  • 4
  • 3
  • 21
    This is no longer correct/accurate. See https://github.com/dotnet/runtime/issues/38418#issuecomment-706803864 – Youssef13 Oct 12 '20 at 11:26
  • 3
    As side note VS2019 suggests ConvertAll to replace Select + ToList – John Stock Feb 02 '21 at 15:36
  • @JohnStock are you sure? My VS only suggests this because i have Roslynator installed (RCS1077 suggestion). If I disable Roslynator, the suggestion is not made – Caius Jard Sep 07 '21 at 19:38
  • Roslynator no longer suggests this change since there's no real benefit: https://github.com/JosefPihrt/Roslynator/issues/736 – Graham Sep 09 '21 at 16:08
  • 2
    This benchmark I did for .NET 6 suggests that ConvertAll is performing better than Select https://gist.github.com/VaclavElias/b3b521205415d6ae1cf3d5ca9d9cad10. I suggest to do the same tests for your scenarios :) – Vaclav Elias Oct 07 '21 at 14:02
  • 5
    @Graham Roslynator does suggest this change, I am on VS2022 – kpocrz Oct 20 '21 at 13:50
0

I know this is bit late but i have still added because this could be of some use for others in future.

When using it in EntityFramework query expression it is not recommended to use ConvertAll() as it evaluates the expression rather than leaving it as expression for future use. This seriously degrades database query execution performance as it would have to make number of calls before evaluating final expression.

Navap
  • 1,050
  • 9
  • 18
  • 17
    Not quite. As Guffa points out [in this answer](http://stackoverflow.com/a/1571839/1364007), `ConvertAll` [is a method on `List`](https://msdn.microsoft.com/en-us/library/73fe8cwf(v=vs.110).aspx). By the time you *have* the list, you've already evaluated your expression. But you're right - if you don't want to evaluate all, `Select` is preferable. – Wai Ha Lee Dec 13 '15 at 11:29