C#

C# First/FirstOrDefualt, Last/LastOrDefualt 차이

우준세 2025. 5. 28. 15:58
728x90
반응형

 

C#을 사용하여 프로젝트를 진행하면 List<T> 컬렉션을 자주 사용합니다.

그중 특정 조건에 맞는 첫 번째 요소나 마지막 요소를 가져올 때

First, FirstOrDefault, Last, LastOrDefault 같은 LINQ 확장 메서드를 활용할 수 있습니다.

이 메서드들은 비슷해 보이지만 동작 방식에서 중요한 차이가 있으며,

잘못 사용할 경우 런타임 예외로 이어질 수도 있습니다.

이 글에서는 각 메서드의 차이점과 사용 예제를 통해 안전하게 활용하는 방법을 소개하겠습니다. 


 

| First vs FirstOrDefault

| First

First()는 조건에 맞는 첫 번째 요소를 반환합니다.

만약 컬렉션이 비어 있거나 조건에 맞는 요소가 없다면 예외를 발생시킵니다.

 

ex) First() 사용과 예외 발생 

var numbers = new List<int> { 10, 20, 30 };

// 조건 없이 첫 번째 요소 가져오기
int first = numbers.First();
Console.WriteLine(first); // 출력: 10

// 조건을 만족하는 첫 번째 요소 가져오기
int firstOver15 = numbers.First(n => n > 15);
Console.WriteLine(firstOver15); // 출력: 20

// 빈 리스트에서 First 사용 시 예외 발생
var emptyList = new List<int>();
int error = emptyList.First(); // InvalidOperationException 발생

 

| FirstOrDefault

FirstOrDefault()는 조건에 맞는 첫 번째 요소를 반환하되, 없으면 기본 값(default)을 반환합니다.

First()와 가장 큰 차이 점은 예외를 발생하지 않는다는 점입니다.

 

ex) FirstOrDefault() 사용

var numbers = new List<int> { 10, 20, 30 };

// 조건 없는 첫 번째 요소
int first = numbers.FirstOrDefault();
Console.WriteLine(first); // 출력: 10

// 조건 만족 못하면 기본값 반환 (int는 0)
int notFound = numbers.FirstOrDefault(n => n > 100);
Console.WriteLine(notFound); // 출력: 0

// 빈 리스트에서도 예외 없이 기본값 반환
var emptyList = new List<int>();
int result = emptyList.FirstOrDefault();
Console.WriteLine(result); // 출력: 0

| Last vs LastOrDefault

| Last

Last()는 리스트에서 마지막 요소를 반환합니다. 조건이 있을 경우, 조건을 만족하는 마지막 요소를 반환합니다.

마찬가지로 조건에 맞는 요소가 없거나 리스트가 비어있으면 예외가 발생합니다.

 

ex) Last() 사용과 예외 발생 

var numbers = new List<int> { 10, 20, 30 };

// 마지막 요소
int last = numbers.Last();
Console.WriteLine(last); // 출력: 30

// 조건을 만족하는 마지막 요소
int lastUnder30 = numbers.Last(n => n < 30);
Console.WriteLine(lastUnder30); // 출력: 20

// 조건에 맞는 요소가 없으면 예외 발생
int error = numbers.Last(n => n > 100); // InvalidOperationException 발생

 

| LastOrDefault

LastOrDefault()는 조건에 맞는 마지막 요소를 반환하되,

조건을 만족하는 요소가 없으면 기본값을 반환합니다.

 

ex) LastOrDefault() 사용

var numbers = new List<int> { 10, 20, 30 };

// 마지막 요소 반환
int last = numbers.LastOrDefault();
Console.WriteLine(last); // 출력: 30

// 조건에 맞는 마지막 요소 반환
int lastOver15 = numbers.LastOrDefault(n => n > 15);
Console.WriteLine(lastOver15); // 출력: 30

// 조건을 만족하는 요소가 없으면 기본값 반환
int notFound = numbers.LastOrDefault(n => n > 100);
Console.WriteLine(notFound); // 출력: 0

 


| 기본값 (Default) 의미

앞서 사용한 FirstOrDefault()와 LastOrDefault()에서 반환되는 기본 값이란

타입 T의 기본 값을 의미합니다.

 

타입 기본값 (default(T))

타입 기본값 default(T)
int 0
bool false
string null
object null
DateTime DateTime.MinValue
사용자 정의 구조체 각 필드의 기본값

 

따라서 앞서 진행한 예시들의 타입이 List<int>이므로 기본값이 0이 반환되었습니다.

 

제가 처음 해당 메서드를 사용했을 때 List에 있는 값이 아닌데 어떻게 나오지?라는 의문을 가졌으며 

실제로는 리스트에 아무것도 없거나, 조건을 만족하는 요소가 없을 때 반환되는 기본값일 뿐입니다

 

| 참조형 타입에서는 null이 반환됨

var names = new List<string>();
string name = names.FirstOrDefault();
Console.WriteLine(name == null); // true

 

string은 참조형(reference type)이라서 기본값은 null입니다.

따라서 비어 있는 List<string>에서 FirstOrDefault()를 호출하면 null이 반환됩니다.

 


| 마무리

이번 포스팅은 First, FirstOrDefault와 Last, LastOrDefault의 차이 점에 대해 설명했습니다.

 

null 병합 연산자인 ??나 조건문과 같이 사용한다면 조금 더 안전한 코드를 구성할 수 있을 것 같네요

 

틀린 점이나 질문이 있으시면 댓글로 남겨주세요.

감사합니다 :) 

 

728x90
반응형