У меня есть список:
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(), поскольку он оценивает выражение, а не оставляет его в качестве выражения для будущего использования. Это серьезно ухудшает производительность выполнения запросов к базе данных, поскольку для оценки окончательного выражения потребовалось бы сделать количество вызовов.