C#
Select method
ConvertAll method
LINQ
programming differences

Difference between Select and ConvertAll in C

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Select and ConvertAll both transform elements from one type into another, but they belong to different parts of the C# ecosystem and behave differently. The biggest differences are where they are available, when they execute, and what type they return. If you pick between them deliberately, the code becomes clearer and sometimes more efficient.

Select Is A LINQ Projection

Select is an extension method from LINQ. It works on any source that implements IEnumerable<T>, so it is broadly applicable across arrays, lists, query results, and many custom sequences.

csharp
1using System;
2using System.Collections.Generic;
3using System.Linq;
4
5var numbers = new List<int> { 1, 2, 3, 4 };
6IEnumerable<string> labels = numbers.Select(n => $"Value={n}");
7
8foreach (var label in labels)
9{
10    Console.WriteLine(label);
11}

The important detail is that Select uses deferred execution. The projection does not necessarily run when you call Select; it runs when you enumerate the result.

ConvertAll Belongs To List<T>

ConvertAll is an instance method on List<T>. It is narrower in scope because it only works when the source is already a List<T>, but it returns a new List<TResult> immediately.

csharp
1using System;
2using System.Collections.Generic;
3
4var numbers = new List<int> { 1, 2, 3, 4 };
5List<string> labels = numbers.ConvertAll(n => $"Value={n}");
6
7Console.WriteLine(labels.Count);
8Console.WriteLine(labels[0]);

This eager execution can be useful when you specifically want a concrete list right away and you are already holding a List<T>.

Deferred Versus Immediate Execution

This is the behavioral difference that matters most in real code.

csharp
1using System;
2using System.Collections.Generic;
3using System.Linq;
4
5var numbers = new List<int> { 1, 2, 3 };
6var projected = numbers.Select(n => n * 10);
7
8numbers.Add(4);
9
10foreach (var item in projected)
11{
12    Console.WriteLine(item);
13}

This prints 10, 20, 30, and 40 because the query runs when enumerated, after the list has changed.

Now compare that with ConvertAll:

csharp
1using System;
2using System.Collections.Generic;
3
4var numbers = new List<int> { 1, 2, 3 };
5var converted = numbers.ConvertAll(n => n * 10);
6
7numbers.Add(4);
8
9foreach (var item in converted)
10{
11    Console.WriteLine(item);
12}

This prints only 10, 20, and 30 because the new list was created immediately.

Return Type Changes How You Compose Code

Select returns IEnumerable<TResult>, which makes it ideal for query pipelines.

csharp
1using System;
2using System.Collections.Generic;
3using System.Linq;
4
5var names = new List<string> { "Ada", "Grace", "Linus" };
6
7var result = names
8    .Select(name => name.ToUpperInvariant())
9    .Where(name => name.Length > 3);
10
11foreach (var item in result)
12{
13    Console.WriteLine(item);
14}

ConvertAll returns List<TResult>, so it is less query-oriented. It is better when the end goal is already "give me another list."

When ConvertAll Is Reasonable

ConvertAll is not obsolete or wrong. It is a good fit when all of the following are true:

  • the source is a List<T>,
  • you want eager materialization,
  • you want the result as List<TResult>,
  • you do not need a larger LINQ chain.

That makes it a pragmatic choice in simple collection conversion code.

When Select Is Usually Better

Use Select when you need flexibility. It works with more collection types, composes naturally with Where, OrderBy, and GroupBy, and lets you decide later whether to materialize with ToList, ToArray, or not at all.

You also get the indexed overload:

csharp
1using System;
2using System.Collections.Generic;
3using System.Linq;
4
5var names = new List<string> { "Ada", "Grace", "Linus" };
6var indexed = names.Select((name, index) => $"{index}: {name}");
7
8foreach (var item in indexed)
9{
10    Console.WriteLine(item);
11}

That kind of composition is exactly where LINQ is strongest.

Common Pitfalls

  • Using Select and forgetting that the query is deferred until enumeration.
  • Using ConvertAll on a source that is not actually a List<T>.
  • Calling Select(...).ToList() and then assuming it behaves exactly like ConvertAll in every surrounding context.
  • Choosing ConvertAll inside a longer query pipeline where Select would read more naturally.
  • Ignoring return types and then wondering why later LINQ operators or list-only methods are unavailable.

Summary

  • 'Select is a LINQ projection that works on any IEnumerable<T>.'
  • 'ConvertAll is a List<T> method that eagerly returns a new List<TResult>.'
  • The most important difference is deferred execution versus immediate execution.
  • Use Select for flexible query composition and broad collection support.
  • Use ConvertAll when you already have a List<T> and want another list immediately.

Course illustration
Course illustration

All Rights Reserved.