Разница между Select и ConvertAll в С#

У меня есть список:

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

В чем разница между этими двумя способами?

Ответ 1

Select является методом расширения LINQ и работает на всех объектах IEnumerable<T>, тогда как ConvertAll реализуется только List<T>. Метод ConvertAll существует с .NET 2.0, тогда как LINQ был введен с 3.5.

Вы должны одобрить Select над ConvertAll, поскольку он работает для любого типа списка, но они делают то же самое в основном.

Ответ 2

ConvertAll не является расширением, это метод в классе списка. Вам не нужно вызывать ToList в результате, поскольку он уже представляет собой список:

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

Итак, разница в том, что метод ConvertAll может использоваться только в списке и возвращает список. Метод Select может использоваться в любой коллекции, которая реализует интерфейс IEnumerable<T>, и возвращает IEnumerable<T>.

Кроме того, они выполняют обработку по-разному, поэтому у них есть свои сильные стороны в разных ситуациях. Метод ConvertAll запускается через список и создает новый список за один раз, а метод Select использует ленивое выполнение и обрабатывает только те элементы, которые вам нужны. Если вам не нужен весь элемент, метод Select более эффективен. С другой стороны, после того, как ConvertAll вернул список, вам не нужно сохранять исходный список.

Ответ 3

Я знаю, что это немного поздно, но я все же добавил, потому что это может быть полезно для других в будущем.

При использовании в выражении запроса EntityFramework не рекомендуется использовать ConvertAll(), поскольку он оценивает выражение, а не оставляет его в качестве выражения для будущего использования. Это серьезно ухудшает производительность выполнения запросов к базе данных, поскольку для оценки окончательного выражения потребовалось бы сделать количество вызовов.