LINQ 사용시 흔한 실수 : FirstOrDefault()

[제목] LINQ 사용시 흔한 실수 : FirstOrDefault()

.NET Framework에 LINQ 가 도입된 이후, 많은 C# 개발자들이 점점 더 LINQ를 애용하고 있다. 이는 LINQ를 사용하지 않으면 별도의 작은 함수들을 여러 개 만들어야 하는 불편함들을 LINQ가 해소해 주기 때문일 것이다. 그런데, 자주 LINQ를 사용하는 개발자들도 흔히 하는 실수가 있는데, 이는 Single(), SingleOrDefault(), First(), FirstOrDefault() 와 같은 메서드를 잘못 사용하는 경우이다.

예를 들어, 다음 C# 코드는 무었이 잘못되었을까?
// 버그 예
string xml = jobs.FirstOrDefault(p => p.ID = val).Value;

실제로 C# 코드에 꽤 능숙한 친구가 이 코드를 작성하였는데, 실제 프로덕션 시스템에서도 곧 잘 도는 프로그램이었다. 하지만, 어느날 입력변수 val 이 jobs 컬렉션 내에 없는 값을 받아들였을 때, 문제가 발생하였다. NullReference Exception이 발생한 것이다. 물론 LINQ에 익숙한 개발자는 금방 알아차렸겠지만, 이는 FirstOrDefault() 메서드가 컬렉션에 없는 row를 찾으므로 NULL을 리턴하기 때문이다. NULL 객체에서 Value라는 속성을 호출하였으니 에러가 발생한 것이다. 따라서, FirstOrDefault() 혹은 SingleOrDefault() 를 호출할 때는 항상 NULL이 리턴되는 경우를 처리해주어야 한다.

// 수정 예제
var job = jobs.FirstOrDefault(p => p.ID = val);
string xml;
if (job == null) 
      xml = string.Empty;
else 
      xml = job.Value;

그렇다면 LINQ에서 언제 FirstOrDefault()를 쓰고, 언제 First()를 쓰는가? FirstOrDefault() 메서드는 리턴되는 ResultSet이 NULL일 수 있을 때 사용하고, First() 메서드는 리턴값이 반드시 존재할 때, 그 해당 조건의 첫번재 row를 리턴할 때 사용한다. 만약 First() 호출에서 리턴 결과가 없으면 Exception을 발생시키게 된다.

Single() 과 SingleOrDefault() 메서드도 동일하다. Single()은 반드시 결과 1 row가 존재한다는 가정하게 사용하는 것으로 만약 존재하지 않으면 Exception을 발생시켜도 좋다고 지정하는 것이다.

일반적으로 Exception 핸들링을 개발자가 처리하는 것이 좋으므로, 필자는 First(), Single() 보다 FirstOrDefault() 혹은 SingleOrDefault()를 선호하는 편이다. 물론 경우에 따라 Single(), First()도 문제 없는 경우가 있지만...
 



본 웹사이트는 광고를 포함하고 있습니다. 광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.