record
C# 9.0 부터 도입된 참조형(reference type) 선언 키워드다.
기본적인 형태는 class와 유사하지만, 데이터 저장에 특화된 불변(Immutable) 객체를 간단히 정의할 수 있다는 점이 특징이다.
주로 값 자체를 비교해야 하는 경우, 또는 DTO(Data Transfer Object), 모델 클래스, 게임 데이터 등에서 유용하다.
사용 법은 아래와 같다.
public record Player(string Name, int Level);
이렇게 정의만 해도
생성자, 일기 전용 프로퍼티, 값 기반의 Equals 및 GetHashCode, ToString() 오버라이드 등이 자동으로 제공된다.
class vs record
| class | record | |
| 비교 방식 | 참조 비교(Reference Equality) | 값 비교(Value Equality) |
| 불변성 | 기본적으로 가변(Mutable) | 기본적으로 불변(Immutable) |
| 주 목적 | 객체의 동작(Behavior) 정의 | 데이터 저장 및 전달 |
| 코드 양 | 생성자/Equals/ToString 수동 구현 필요 | 자동 생성 |
예시
class PlayerClass
{
public string Name { get; init; }
public int Level { get; init; }
}
record PlayerRecord(string Name, int Level);
var p1 = new PlayerRecord("Ash", 10);
var p2 = new PlayerRecord("Ash", 10);
Console.WriteLine(p1 == p2); // True (값 비교)
class라면 두 객체는 서로 다른 참조라서 == 결과 false가 돼야한다.
record는 값 비교를 수행하기 때문에, 내용이 같으니 true가 출력된다.
init 전용 Setter
record와 함께 자주 쓰이는 기능이 바로 init 접근자다.
이는 초기화 시점에만 값을 할당할 수 있고, 이후 변경할 수 없는 프로퍼티를 정의할 때 사용된다.
public record Monster
{
public string Name { get; init; }
public int HP { get; init; }
}
var slime = new Monster { Name = "Slime", HP = 100 };
// slime.HP = 200; // 오류 (init 전용이므로 수정 불가)
with
with을 통해 기존 객체를 복사하면서 일부 속성만 바꾸는 식으로 새로운 객체를 만들 수 있다.
이를 통해 불변 객체를 다룰 수 있다.
var pikachu = new PlayerRecord("Pikachu", 5);
var raichu = pikachu with { Level = 20 };
Console.WriteLine(pikachu); // PlayerRecord { Name = Pikachu, Level = 5 }
Console.WriteLine(raichu); // PlayerRecord { Name = Pikachu, Level = 20 }
언제 쓸까?
- DTO (데이터 전송 객체)
- 예: 네트워크 통신, DB ↔ 게임 서버 데이터 매핑
- record는 데이터 값 자체만을 중요시하기 때문에 DTO 설계에 적합하다.
- 불변성을 활용해야 할 때
- 멀티스레드 환경에서 데이터 안정성 보장
- 복잡한 상태 변경 없이 새로운 버전의 데이터를 만들어내는 경우
- 게임 개발에서의 예시
- 캐릭터 스탯 정보
- 아이템 속성 (이름, 공격력, 희귀도 등)
- 로그 기록이나 이벤트 데이터
public record Item(string Name, int Power, string Rarity);
var sword = new Item("Iron Sword", 10, "Common");
var sword2 = new Item("Iron Sword", 10, "Common");
Console.WriteLine(sword == sword2); // True
장단점
장점
- 값 기반 비교(Value Equality) 자동 제공
- 불변 객체 설계 용이
- DTO, 게임 데이터, 설정값 등에 최적화
- with 키워드로 손쉽게 불변 객체 복사 가능
- ToString() 자동 오버라이드 → 디버깅 편리
단점
- 클래스보다 약간의 런타임 비용이 발생할 수 있음
- 지나치게 남용하면 객체 지향적인 설계보다 단순 데이터 구조화로 기울어짐
- C# 9.0 이상에서만 사용 가능 → 레거시 프로젝트에는 도입 제한
클래스는 행동 중심이고, 레코드는 데이터 중심이라고 이해하면 구분이 쉽다.
'C#' 카테고리의 다른 글
| C# - 자료구조 실습 - 인벤토리 (0) | 2025.09.25 |
|---|---|
| C# - 자료구조 : Indexer, List, LinkedList (0) | 2025.09.24 |
| C# - StringBuilder (0) | 2025.09.23 |
| C# - 캡쳐(Capture), 클로져(Closure) - feat React.useState (0) | 2025.09.23 |
| C# - 델리게이트 (Delegate) (0) | 2025.09.22 |