Find () 및 Where (). FirstOrDefault ()


161

나는 종종 사람들 Where.FirstOrDefault()이 검색을하고 첫 번째 요소를 얻는 것을 사용하는 것을 본다 . 왜 사용하지 Find()않습니까? 다른쪽에 이점이 있습니까? 나는 차이를 말할 수 없었다.

namespace LinqFindVsWhere
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> list = new List<string>();
            list.AddRange(new string[]
            {
                "item1",
                "item2",
                "item3",
                "item4"
            });

            string item2 = list.Find(x => x == "item2");
            Console.WriteLine(item2 == null ? "not found" : "found");
            string item3 = list.Where(x => x == "item3").FirstOrDefault();
            Console.WriteLine(item3 == null ? "not found" : "found");
            Console.ReadKey();
        }
    }
}

45
FWIW는 list.FirstOrDefault(x => x == "item3");모두 사용하는 것보다 더 간결 .Where하고를 .FirstOrDefault.
Kirk Woll

@ Kirk, 내 다음 질문은 그들이 찾기를 전혀 추가하지 않은 이유 일 것입니다. 좋은 팁입니다. 내가 생각할 수있는 유일한 것은 FirstOrDefault가 null 이외의 다른 기본값을 반환 할 수 있다는 것입니다. 그렇지 않으면 그것은 무의미한 추가처럼 보입니다.
KingOfHypocrites

8
FindLINQ보다 이전입니다. (.NET 2.0에서 사용할 수 있었고 람다를 사용할 수 없었습니다. 일반적인 방법이나 익명의 방법을 사용해야했습니다)
Kirk Woll

답변:


205

Find방법 은 어디에 있습니까 IEnumerable<T>? (수사적 질문입니다.)

WhereFirstOrDefault방법은 다음과 같은 순서의 여러 종류에 대하여 적용 할 수있는 List<T>, T[], Collection<T>구현이 있다는 등 모든 순서 IEnumerable<T>이러한 방법을 사용할 수 있습니다. Find에 대해서만 사용할 수 있습니다 List<T>. 일반적으로 더 적용 가능한 방법은 더 재사용 가능 하며 더 큰 영향을 미칩니다.

다음 질문은 그들이 왜 찾기를 추가했는지에 대한 것입니다. 좋은 팁입니다. 내가 생각할 수있는 유일한 것은 FirstOrDefault가 null 이외의 다른 기본값을 반환 할 수 있다는 것입니다. 그렇지 않으면 그것은 무의미한 추가처럼 보입니다.

FindList<T>선행 다른 방법. List<T>.NET 2.0에서 제네릭과 함께 추가 Find되었으며 해당 클래스의 API의 일부였습니다. WhereFirstOrDefault위한 확장 방법으로 첨가 IEnumerable<T>이후 .NET 버전이다 Linq를 가진. Linq가 2.0 릴리스와 함께 존재하면 Find추가되지 않았을 것이라고 확신 할 수 는 없지만 이전 버전에서 사용되지 않거나 중복 된 이전 .NET 버전에서 제공되는 많은 다른 기능의 경우 일 것입니다.


85
보완하기 위해 : Where 및 First 또는 FirstOrDefault를 호출 할 필요가 없습니다. First 또는 FirstOrDefault를 사용하면 검색 조건자를 지정하여 Where 호출을 불필요하게 만들 수 있습니다.
Robson Rocha

4
그러나 Where(condition).FirstOrDefault()적어도 FirstOrDefault(condition)혼자서 보다 때로는 더 잘 최적화 합니다. 우리는 가능한 경우 항상 Where()향상된 성능을 얻기 위해 사용 합니다.
Suncat2000

7
Suncat2000 @ 예를 들어하시기 바랍니다 제공
콘스탄틴 Salavatov

2
@ Suncat2000 표현력 때문에 Linq를 사용하고 있으며 선언적 코드를 작성하려고합니다. 이러한 미세한 개선에 대해서는 걱정하지 않아도되며, 향후 구현에서도 변경 될 수 있습니다. 또한 너무 일찍 최적화하지 마십시오
Piotr Falkowski

50

방금 오늘 80K 객체 목록에서 몇 가지 테스트를 수행 Find()하여 Wherewith을 사용하는 것보다 최대 1000 % 빠릅니다 FirstOrDefault(). 나는 타이머를 테스트하기 전과 후에야 그것을 몰랐습니다. 때로는 같은 시간이었고 그렇지 않으면 더 빨랐습니다.


6
Where ANDOrDefault로 사용해 보셨습니까? FirstOrDefault만으로 시도하고 Find ()가 여전히 더 나은지 확인하십시오.
MVCKarl

5
.ToList()또는 .ToArray()로 실제로 쿼리를 수행하여 결과를 구체화하지 않은 것처럼 들립니다 .
Andrew Morton

4
이는 Find기본 키 (따라서 인덱스)를 사용 하기 때문 입니다. 반면 Where일반 SQL 쿼리 인
percebus

4
EF6부터 Find와 FirstOrDefault는 모두 정확히 동일한 SQL 문을 생성합니다. context.Database.Log = Console.Write를 수행하여 콘솔 앱에서 SQL을 볼 수 있습니다. sited 예제는 기본 키가있는 DB에 대한 것이 아니라 문자열 목록에 대해 메모리 내 "찾기"를 사용하는 것입니다. 람다 식 구문 분석을 수행 할 필요가없는 Find 절의 명령문 변환이이 경우 성능 향상의 원인 일 수 있습니다. 데이터베이스에 대해 RL 상황의 차이를 알 수 있을지 의심됩니다 ... 또한 두 번째 대신 먼저 찾기를 사용하여 테스트했는지 궁금합니다.
C.List

2
이 성능 향상은 find ()가 DB를 누르기 전에 캐시에서 객체를 검사하는 반면 where ()는 항상 DB를 가져 와서 객체를 가져옵니다
Gaurav

35

데이터 소스가 Entity Framework 인 경우 매우 중요한 차이점이 있습니다 Find. '추가됨'상태에서 아직 유지되지 않았지만 그렇지 않은 엔티티를 찾습니다 Where. 이것은 의도적으로 설계된 동작입니다.



1

Anthony와 더불어 Where()모든 레코드를 통해 방문한 다음 결과를 반환하는 반면 Find(), 술어가 주어진 술어와 일치하는 경우 모든 레코드를 탐색 할 필요가 없습니다.

테스트 클래스 목록 idname속성이 있다고 가정 해보십시오.

 List<Test> tests = new List<Test>();
 tests.Add(new Test() { Id = 1, Name = "name1" });
 tests.Add(new Test() { Id = 2, Name = "name2" });
 tests.Add(new Test() { Id = 3, Name = "name3" });
 tests.Add(new Test() { Id = 4, Name = "name2" }); 
 var r = tests.Find(p => p.Name == "name2");
 Console.WriteLine(r.Id);

의 결과를 제공하고 방문을 22 회만 제공합니다. 결과를 제공하는 데 필요한 정보를 찾으십시오. 그러나 사용하는 경우 모든 레코드를 방문하여 결과를 얻습니다.Where().FirstOrDefault()

따라서 컬렉션의 레코드에서 얻은 첫 번째 결과 만 Find()더 적합하다는 것을 알고 있으면Where().FirtorDefault();


4
그러나 Where (). FirstOrDefault ()를 사용하면 모든 레코드를 방문하고 결과를 얻습니다. 아니. FirstOrDefault체인을 '버블 업'하고 모든 것을 열거하지 않습니다. 실제로 모든 선택기 / 조건자가 다음에 전달되므로 체인의 마지막 방법이 실제로 작업을 수행하기 때문에 더 나은 표현이 없으면 '버블 업'이라는 용어를 사용합니다.
Silvermind

1

와우, 오늘 Youtube에서 MicrosofToolbox의 EF 튜토리얼을 볼 수 있습니다. 그는 쿼리에서 Find () 및 FirstOrDefault (condition) 사용에 대해 말했으며 Find ()는 해당 객체에서 수행 한 데이터를 추가하거나 편집하거나 삭제하지만 아직 데이터베이스에 저장하지 않은 데이터를 검색하지만 FirstOrDefault는 이미 저장된 것을 찾으십시오


-1

Find()는 IEnumerable에 해당합니다 FirstOrDefault(). 전체 배열을 거치고 첫 번째 항목을 찾기 위해 해당 목록을 반복 .FirstOrDefault()하기 때문에 .Where ()와 체인을 연결해서는 안됩니다 .Where(). FirstOrDefault()메소드에 검색 술어를 넣어서 시간을 크게 절약 할 수 있습니다.

또한 .Find()특정 시나리오 에서 Find ()의 성능과 FirstOrDefault ()의 성능에 대한 성능에 대한 자세한 내용을 보려면이 스레드에 연결된 질문을 읽으십시오.


이것은 위의 답변과 중복됩니다. 또한 해당 답변에 대한 Silvermind의 의견을 참조하십시오.
carlin.scott
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.