Microsoft .NET/C#
[C#] record 타입 정리, class와 차이와 with 식
전자기린
2026. 11. 10. 00:42

C# 9에서 추가된 record를 실무에서 쓸 때 필요한 부분만 정리했습니다.
절차
- class와의 차이
- 값 비교와 with 식
- Deconstruct와 패턴 매칭
- 주의할 점
1. class와의 차이
// 한 줄로 값 객체 정의
public record UserDto(int Id, string Name);
// 위 한 줄이 아래를 자동 생성합니다
public class UserDto
{
public int Id { get; init; }
public string Name { get; init; }
public UserDto(int id, string name) => (Id, Name) = (id, name);
// 값 기반 Equals, GetHashCode, ToString
}init 접근자라 생성 후에는 바꿀 수 없고, Equals가 값 기준으로 동작합니다.
2. 값 비교와 with
var a = new UserDto(1, "Kim");
var b = new UserDto(1, "Kim");
Console.WriteLine(a == b); // True (class였다면 False)
var c = a with { Name = "Lee" }; // 일부만 바꾼 새 인스턴스
Console.WriteLine(c.Name); // Lee
3. Deconstruct와 패턴 매칭
var (id, name) = a;
if (a is { Id: > 0, Name: "Kim" })
{
// 속성 패턴
}4. 주의할 점
- 컬렉션 속성은 참조 비교입니다 — 내용이 같아도
==가 False record class는 상속 가능,record struct는 값 형식- EF Core 엔티티에는 보통 쓰지 않습니다 — 생성자 바인딩·변경 추적 때문에 class가 편합니다
// 컬렉션까지 값 비교하려면 직접 구현
public record OrderDto(int Id, IReadOnlyList<string> Items)
{
public virtual bool Equals(OrderDto? other) =>
other is not null && Id == other.Id &&
Items.SequenceEqual(other.Items);
public override int GetHashCode() => HashCode.Combine(Id, Items.Count);
}정리
- DTO·설정·결과 값에는 record
- 변경이 잦은 도메인 객체·EF 엔티티에는 class
- 컬렉션 속성은 값 비교가 되지 않으니 직접 구현