C #에서 Select와 ConvertAll의 차이점


117

몇 가지 목록이 있습니다.

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

이 두 가지 방법의 차이점은 무엇입니까?


16
ConvertAll () 후에 .ToList ()가 필요하지 않습니다.
Gleno 2011

ConvertAll 들어 본 적이 새로운 오늘 뭔가를 알고있어
아 미트 Bisht에게

답변:


117

SelectLINQ 확장 방법이며 모두에서 작동 IEnumerable<T>하는 반면 개체 ConvertAll만에 의해 구현됩니다 List<T>. 이 ConvertAll방법은 .NET 2.0부터 존재하지만 LINQ는 3.5에서 도입되었습니다.

당신은 선호합니다 Select이상 ConvertAll이 목록의 모든 종류의 작품으로,하지만 그들은 기본적으로 동일한 작업을 수행.


7
그리고 공연은 어떻습니까? 목록이있는 경우 ConvertAll 또는 Select를 사용하는 것이 더 성능이 좋습니까?
Nicolas

@Nicolas : 총 실행 시간은 거의 동일하지만 처리 방식이 다르므로 서로 다른 상황에 적합합니다. 내 대답에 그것에 대해 몇 가지를 추가했습니다.
Guffa 2011

3
Select과 비교할 수 없습니다 ConvertAll. 전자는 시퀀스의 모든 항목을 선택하고 원하는대로 자유롭게 할 수 있습니다. 후자는 명확한 의도를 가지고 있습니다 :이 항목을 다른 것으로 변환하십시오.
Tim Schmelter

1
Interrestingly, List <T> 클래스에는 LINQ에서 거의 정확히 일치하는 여러 메서드가 포함되어 있습니다. 존재 -> 모든 찾기 -> 첫째, findall은 -> 여기서, FindLast -> 마지막으로, TrueForAll -> 모든
Mikal 샤 흐트 젠슨

ConvertAll과 Select의 차이점은 ConvertAll이 미리 목록의 크기를 할당합니다. 큰 시퀀스의 경우 성능에 차이가 있습니다. 따라서 성능이 목표라면 ConvertAll을 사용하십시오. 성능이 문제가되지 않는 경우 Select를 사용하면 언어가 좀 더 관용적이며 향후 독자에게 성능이 문제가되지 않았 음을 알립니다.
Durdsoft

82

ConvertAll확장이 아니라 목록 클래스의 메서드입니다. ToList이미 목록이므로 결과 를 호출 할 필요가 없습니다 .

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

그래서 차이점은 ConvertAll 메서드는 목록에서만 사용할 수 있으며 목록을 반환한다는 것입니다. 이 Select메서드는 IEnumerable<T>인터페이스 를 구현하는 모든 컬렉션에서 사용할 수 있으며 IEnumerable<T>.

또한 처리 방식이 다르기 때문에 상황에 따라 강점이 있습니다. 이 ConvertAll메서드는 목록을 통해 실행되고 한 번에 새 목록을 생성하는 반면 Select메서드는 지연 실행을 사용하고 필요한 항목 만 처리합니다. 모든 항목이 필요하지 않은 경우 Select방법이 더 효율적입니다. 반면에 ConvertAll목록을 반환 한 후에는 원래 목록을 유지할 필요가 없습니다.


틀림없이 "원래 목록을 유지"할 필요는 없습니다. GC에서 필요에 따라 수행됩니다.
user2864740

8
@ user2864740 : 예, 소스가 엄격하게 메모리의 목록이면 참입니다. 예를 들어 파일에서 읽은 경우 .NET Framework에서 결과를 처리 할 때까지 파일을 열어 두어야합니다 Select.
Guffa

19

첫 번째 답변은 허용되는 답변이 아니어야합니다. 저는 2007 년 C # Microsoft MVP입니다.

수락 응답과는 대조적으로, ConvertAll의 조합보다 훨씬 더 효율적입니다 SelectToList() 입니다.

우선, ConvertAll엄격하게 더 빠르며이를 위해 최소한의 메모리를 사용합니다. Array.ConvertAll 대 Select 및 ToArray와 동일합니다. 이것은 더 큰 길이의 배열이나 루프 내의 많은 호출에서 훨씬 더 분명해질 것입니다.

1) ConvertAll최종 목록의 크기를 알고 기본 배열을 재할 당하지 않습니다. ToList()는 배열의 크기를 여러 번 계속 조정합니다.

2) ToList인터페이스 IEnumerable<>호출 속도가 느리지 만ConvertAll 추가 호출이나 범위 확인없이 기본 배열을 반복합니다.

3) 선택하면 추가 IEnumerable<T>개체 가 생성됩니다 .


1

나는 이것이 조금 늦었다는 것을 알고 있지만 이것은 미래에 다른 사람들에게 유용 할 수 있기 때문에 여전히 추가했습니다.

EntityFramework 쿼리 표현식에서 사용할 때 나중에 사용하기 위해 표현식으로 남겨 두지 않고 표현식을 평가하기 때문에 ConvertAll ()을 사용하지 않는 것이 좋습니다. 최종 표현식을 평가하기 전에 여러 번 호출해야하므로 데이터베이스 쿼리 실행 성능이 심각하게 저하됩니다.


9
좀 빠지는. Guffa가 지적 하듯 이 대답에 , ConvertAll 에 방법이다List<T> . 목록 이 있을 때까지 이미 표현을 평가 한 것입니다. 그러나 당신이 옳습니다-당신이 모든 것을 평가하고 싶지 않다면, Select바람직합니다.
Wai Ha Lee
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.