Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

C# LINQ에서 Last()와 LastOrDefault()의 차이점 완벽 정리

C# LINQ에서 Last()LastOrDefault()는 모두 조건에 일치하는 마지막 요소를 반환한다는 공통점이 있습니다. 하지만 두 메서드의 핵심적인 차이는 결과가 존재하지 않을 때의 동작 방식에 있습니다.

  • Last(): 주어진 조건에 일치하는 요소가 없으면 InvalidOperationException 예외를 발생시킵니다.
  • LastOrDefault(): 조건에 일치하는 요소가 없을 경우 예외를 던지지 않고 기본값(null)을 반환합니다.

언제 어떤 메서드를 사용해야 할까?

Last()는 시퀀스에 최소한 하나 이상의 요소가 반드시 존재한다고 확신할 수 있을 때 사용하는 것이 좋습니다. 반면, 데이터의 존재 여부를 확신할 수 없다면 LastOrDefault()를 사용하여 예외 발생으로 인한 런타임 오류를 방지하는 것이 안전합니다.

예제 1: 요소가 존재하는 경우

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp {
    public class Student {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    class Program {
        static void Main() {
            var studentsList = new List<Student> {
                new Student { Id = 1, Name = "John" },
                new Student { Id = 2, Name = "Jack" },
                new Student { Id = 1, Name = "Jill" }
            };

            var lastOrDefaultStudent = studentsList.LastOrDefault(student => student.Id == 1);
            var lastStudent = studentsList.Last(student => student.Id == 1);

            Console.WriteLine($"LastOrDefault: {lastOrDefaultStudent.Id} {lastOrDefaultStudent.Name}");
            Console.WriteLine($"Last: {lastStudent.Id} {lastStudent.Name}");
            Console.ReadLine();
        }
    }
}

실행 결과

LastOrDefault: 1 Jill
Last: 1 Jill

위 코드에서는 Id == 1인 학생이 목록에 존재하므로, 두 메서드 모두 해당 조건과 일치하는 마지막 요소인 "Jill"을 정상적으로 반환합니다.

예제 2: 요소가 존재하지 않는 경우

using System;
using System.Collections.Generic;
using System.Linq;

namespace DemoApplication {
    public class Student {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    class Program {
        static void Main(string[] args) {
            try {
                var studentsList = new List<Student> {
                    new Student { Id = 1, Name = "John" },
                    new Student { Id = 2, Name = "Jack" }
                };

                // Id가 3인 학생은 존재하지 않음
                var lastOrDefaultStudent = studentsList.LastOrDefault(student => student.Id == 3);
                var value = lastOrDefaultStudent == null ? "null" : "";
                Console.WriteLine($"LastOrDefault: {value}");

                // Last() 호출 시 예외 발생
                var lastStudent = studentsList.Last(student => student.Id == 3);
            }
            catch (Exception ex) {
                Console.WriteLine($"Last Exception: {ex.Message}");
                Console.ReadLine();
            }
        }
    }
}

실행 결과

LastOrDefault: null
Last Exception: Sequence contains no matching element

위 예제에서 Id "3"에 해당하는 학생은 studentsList에 존재하지 않습니다. 따라서 LastOrDefault()는 예외 없이 null을 반환하는 반면, Last()는 "Sequence contains no matching element"라는 메시지와 함께 예외를 발생시킵니다.

정리

구분Last()LastOrDefault()
요소가 존재할 때마지막 요소 반환마지막 요소 반환
요소가 없을 때예외 발생 (InvalidOperationException)기본값(null) 반환
권장 상황데이터 존재가 보장될 때데이터 존재 여부가 불확실할 때

결론적으로, 안정성이 중요한 실무 코드에서는 데이터 부재 가능성을 항상 고려하여 LastOrDefault()를 사용하고, 반환값의 null 여부를 확인하는 방어적 프로그래밍 습관을 갖추는 것이 좋습니다.