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>? (수사적 질문입니다.)

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

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

Find에 List<T>선행 다른 방법. List<T>.NET 2.0에서 제네릭과 함께 추가 Find되었으며 해당 클래스의 API의 일부였습니다. Where및 FirstOrDefault위한 확장 방법으로 첨가 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(), 술어가 주어진 술어와 일치하는 경우 모든 레코드를 탐색 할 필요가 없습니다.

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

 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.