본문 바로가기

C#

[C#] LINQ와 Lazy Evaluation(지연 평가)

✅ LINQ란?

LINQ (Language Integrated Query)
C# 코드에서 배열이나 컬렉션을 SQL처럼 필터링, 정렬, 변환할 수 있게 해주는 기능입니다.

🔹 예전 방식

List<int> list = new List<int> { 1, 2, 3, 4, 5 };
List<int> result = new List<int>();
foreach (int i in list)
{
    if (i % 2 == 0) result.Add(i);
}

🔹 LINQ 방식

var result = list.Where(x => x % 2 == 0).ToList();

 

🎯 결과는 동일하지만 코드가 훨씬 짧고 읽기 쉬움

 

✅ LINQ는 왜 쓰는가?

✅ 가독성 코드가 SQL처럼 직관적이고 깔끔함
✅ 체이닝 가능 여러 조건을 연속으로 필터링 가능
✅ 유지보수 편함 반복문보다 수정이 쉬움
✅ 성능도 괜찮음 내부적으로 최적화된 IEnumerable 기반 구조
 

✅ 실무 팁

  • Where → Select → ToList() 순으로 체이닝이 많음
  • First는 조건에 맞는 요소가 반드시 있을 때만 사용
    → 없을 수도 있으면 FirstOrDefault()
  • .ToList()를 붙지 않으면 지연 평가(lazy evaluation) 가 되어 실제로 사용할 때만 실행됨

 

✅ 지연 평가(Lazy Evaluation)란?

필요할 때까지 연산을 미루는 것
즉, 지금 바로 실행하지 않고, 실제로 값을 사용할 때 실행하는 방식입니다.

🔸 예를 들어볼게요

var result = numbers.Where(x => {
    Console.WriteLine($"x = {x}");
    return x % 2 == 0;
});

이 코드를 실행하면 콘솔에 아무것도 안 찍힙니다. 왜냐하면...

foreach (var r in result)
    Console.WriteLine($"결과: {r}");

이 시점이 되어야 Where 안의 코드가 실행되기 때문입니다.

 

✅ 왜 이렇게 작동할까?

LINQ의 대부분 메서드(Where, Select, OrderBy 등)는
.ToList()나 .First() 같은 **끝맺음 메서드(terminal method)**가 호출되기 전까지는 실제로 처리하지 않습니다.

즉, Where()는 “조건을 정해놓고 기다리는 설계도”만 만든 것이고,
그걸 진짜로 사용하려 할 때 실행되는 거예요.

 

✅ 장점 (왜 이렇게 하는가?)

🎯 성능 최적화 필요한 만큼만 처리함 (데이터가 100만 개 있어도, 3개만 뽑으면 3개만 계산)
🧠 메모리 절약 .ToList()로 만들지 않으면 중간 데이터 저장 안 함
📦 스트리밍 처리 대용량 데이터에서도 빠르게 처리 가능함 (yield랑 비슷)
 
⚠️ 단점 / 주의점
  • 중간에 원본 데이터가 바뀌면 결과도 바뀔 수 있음
    (지연 평가라서 "그때 기준"으로 다시 실행됨)
  • 디버깅 시, Where()만 걸고 확인하려 해도 실제로 실행이 안 돼서 빈 값처럼 보일 수 있음
  • 한번 반복할 때마다 새로 실행되므로, .ToList()로 결과를 캐싱하고 쓰는 경우도 많음

'C#' 카테고리의 다른 글

[C#] 구조체를 쓰는 이유  (1) 2025.08.10
[C#] Boxing과 UnBoxing  (3) 2025.07.25
[C#] Garbage Collector  (2) 2025.07.25
[C#] IEnumerable을 쓰는 이유  (2) 2025.07.24
[C#] delegate vs Action  (1) 2025.06.16