핵심 정리
public class Player
{
public string Name { get; set; }
public int Score { get; private set; }
public Player(string name) => Name = name;
public void AddScore(int points) => Score += points;
}
// 생성자로 인스턴스 생성
var player = new Player("Mina");
player.AddScore(10);
Console.WriteLine(player.Score); // 10
// object initializer (public setter가 있는 프로퍼티만 가능)
var p2 = new Player("Jin") { Name = "Jin Park" };문법
어떤 형태가 있나
클래스 카드는 보통 이 네 가지를 같이 보면 빠르게 감이 잡힙니다.
public class Player
{
public string Name { get; set; } = "";
public int Score { get; private set; }
public Player(string name) => Name = name;
public void AddScore(int points) => Score += points;
}
var player = new Player("Mina");
player.AddScore(10);class선언new로 인스턴스 생성- 프로퍼티와 메서드 호출
static멤버는 클래스 이름으로 접근
클래스는 참조 타입
class는 참조 타입입니다. 변수에는 객체 자체가 아니라 힙에 있는 객체를 가리키는 참조가 저장됩니다. 따라서 변수 대입은 복사가 아니라 같은 객체를 공유합니다.
var a = new Player("Mina");
var b = a; // 같은 객체를 참조
b.AddScore(50);
Console.WriteLine(a.Score); // 50 — a도 바뀜!
// 동일 여부 확인
bool sameRef = object.ReferenceEquals(a, b); // true
bool sameVal = a == b; // 기본적으로 참조 비교 (class는 ==가 참조 비교)필드, 프로퍼티, 메서드의 역할
필드는 객체의 원시 데이터를 저장하는 변수입니다. 프로퍼티는 필드에 대한 접근을 제어하는 게이트입니다. 메서드는 객체의 동작을 정의합니다.
public class BankAccount
{
private decimal _balance; // 필드 — 직접 노출하지 않음
// 프로퍼티 — 접근 제어 + 유효성 검사 가능
public decimal Balance
{
get => _balance;
private set
{
if (value < 0) throw new InvalidOperationException("잔액 부족");
_balance = value;
}
}
// 메서드 — 동작 정의
public void Deposit(decimal amount) => Balance += amount;
public void Withdraw(decimal amount) => Balance -= amount;
}필드를 직접 public으로 열어두면 외부 코드가 언제든 값을 바꿀 수 있어 불변식(invariant) 이 깨지기 쉽습니다.
정적 멤버 — 인스턴스 없이 쓰는 멤버
static 멤버는 클래스 자체에 속합니다. 인스턴스를 만들지 않아도 사용할 수 있고, 모든 인스턴스가 같은 값을 공유합니다.
public class Counter
{
public static int Total { get; private set; } = 0; // 정적 프로퍼티
public Counter() => Total++; // 생성될 때마다 증가
public static void Reset() => Total = 0; // 정적 메서드
}
var c1 = new Counter();
var c2 = new Counter();
Console.WriteLine(Counter.Total); // 2
Counter.Reset();선택 기준
| 상황 | 더 적합한 선택 |
|---|---|
| 고유한 상태와 수명이 있는 엔티티 | class |
| 값 자체의 내용 비교가 중요한 데이터 | record |
| 작고 복사 비용이 낮은 값형 데이터 | struct |
var a = new Player("Mina");
var b = a;
// ❌ 새 객체가 생긴다고 착각하기 쉽다
b.AddScore(10);
Console.WriteLine(a.Score); // 10체크포인트
| 개념 | 의미 |
|---|---|
| 클래스 | 객체의 구조(필드, 프로퍼티)와 동작(메서드) 정의 |
| 인스턴스 | new로 생성된 실제 객체 |
| 참조 타입 | 변수 대입 시 같은 객체를 공유 |
static | 인스턴스 없이 클래스 자체에 속한 멤버 |
| 캡슐화 | private 필드 + public 프로퍼티/메서드로 접근 제어 |
주의할 점
var a = b;처럼 클래스 변수를 복사하면 새 객체가 아니라 같은 인스턴스를 가리킵니다. 독립적인 복사본이 필요하면 복사 생성자나 with 표현식(record), 또는 명시적 복제 메서드를 구현해야 합니다.
필드를 모두 public으로 열어두는 것은 캡슐화를 포기하는 것입니다. 외부에서 객체의 상태를 직접 수정할 수 있게 되면 유효성 검사, 이벤트 발행, 캐시 무효화 같은 부가 로직을 끼워 넣기 어려워집니다.
참고 링크
2 sources