C#객체지향

record equality와 with expression

record가 기본 class와 어떻게 다른지, value equality와 `with` expression을 어떤 기준으로 이해하면 좋은지 정리합니다.

마지막 수정 2026년 3월 22일

기본 패턴

csharp
public record User(string Name, int Level);

User first = new("Mina", 5);
User second = first with { Level = 6 };

bool same = first == new User("Mina", 5);

설명

  • record는 "데이터를 표현하는 타입"이라는 의도를 언어 차원에서 더 강하게 드러내는 문법입니다. 기본 class가 reference identity를 중심으로 읽히는 반면, record는 값 중심 모델을 더 자연스럽게 지원합니다.
  • 가장 큰 차이는 value equality입니다. record는 두 인스턴스가 같은 타입이고 구성 멤버 값이 같으면 같은 값으로 비교됩니다. 그래서 DTO, 설정 객체, 읽기 전용 상태 모델 같은 곳에 특히 잘 맞습니다.
  • with expression은 기존 값을 바탕으로 일부만 바꾼 새 객체를 만드는 비파괴적 갱신(nondestructive mutation) 패턴입니다. 불변 스타일 코드를 훨씬 읽기 쉽게 만들어 줍니다.
  • 다만 record가 자동으로 "완전한 불변성"을 주는 것은 아닙니다. 내부에 List<T> 같은 가변 참조 타입이 들어 있으면, record 겉모양과 달리 내부 상태는 여전히 바뀔 수 있습니다.
  • 중요한 판단 기준은 간단합니다. "이 타입의 정체성은 참조인가, 값의 내용인가?" 값의 내용이 핵심이면 record가 더 잘 맞고, 참조 정체성과 수명 관리가 핵심이면 class가 더 자연스러울 수 있습니다.

빠른 정리

항목recordclass
기본 비교 의미value equalityreference equality
with 지원자연스럽게 지원별도 구현 필요
잘 맞는 곳DTO, 상태 모델, 설정 객체서비스, 엔티티, 수명 있는 객체
주의점내부 가변 멤버는 자동 불변 아님값 비교 직접 구현 필요

주의할 점

record에 컬렉션이나 배열처럼 reference equality를 쓰는 멤버가 들어 있으면, "값 중심 모델"이라는 기대가 일부 깨질 수 있습니다. record를 쓸수록 내부 멤버의 불변성과 비교 의미까지 함께 생각하는 편이 중요합니다.

참고 링크

2 sources