0Pricing
C# Academy · 강의

변경 불가능한 객체 패턴

생성 후 변경되지 않는 객체를 설계합니다.

변경 불가능한 객체 패턴은(는) CoddyKit의 무료 C# Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C# Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

변경 불가능한 개체 설계

변경 불가능한 개체는 생성 후 절대 변경되지 않습니다. 변경 불가능성을 사용하면 공유된 변경 가능한 상태와 관련된 여러 종류의 버그를 없앨 수 있으며, 개체를 안전하게 전달하고 캐시할 수 있습니다.

읽기 전용 속성

가장 간단한 변경 불가능 속성은 생성자에서 한 번 할당하는 읽기 전용 속성입니다.

using System;

class Point {
    public int X { get; }
    public int Y { get; }
    public Point(int x, int y) { X = x; Y = y; }
}

var p = new Point(3, 4);
Console.WriteLine(p.X + "," + p.Y); // 3,4

초기화 구문에 사용하는 초기화 전용 속성

변경 불가능성과 편리한 개체 초기화 구문을 함께 사용하려면 init 속성을 사용하세요.

using System;

class Color {
    public int R { get; init; }
    public int G { get; init; }
    public int B { get; init; }
}

var c = new Color { R = 255, G = 128, B = 0 };
Console.WriteLine(c.R + "," + c.G + "," + c.B); // 255,128,0

필수 필드에 required 사용

required + init을 결합하면 필수 필드를 빠뜨릴 수 없고 이후에 변경할 수도 없습니다.

using System;

class Money {
    public required decimal Amount { get; init; }
    public required string Currency { get; init; }
}

var m = new Money { Amount = 9.99m, Currency = "USD" };
Console.WriteLine(m.Amount + " " + m.Currency); // 9.99 USD

변경하는 대신 새 개체 반환하기

변경 불가능한 형식에서는 「변경」 작업을 원본을 그대로 둔 채 새 인스턴스를 반환하는 메서드로 제공합니다.

using System;

class Point {
    public int X { get; init; }
    public int Y { get; init; }
    public Point Move(int dx, int dy) => new Point { X = X + dx, Y = Y + dy };
}

var a = new Point { X = 1, Y = 1 };
var b = a.Move(2, 3);
Console.WriteLine(a.X + "," + a.Y + " -> " + b.X + "," + b.Y); // 1,1 -> 3,4

변경 불가능한 컬렉션

컬렉션 필드에는 변경 불가능하거나 읽기 전용인 컬렉션을 저장하여 개체를 통해 내용이 변경되지 않도록 하세요.

using System;
using System.Collections.Immutable;

class Team {
    public ImmutableList<string> Members { get; init; } = ImmutableList<string>.Empty;
}

var t = new Team { Members = ["Ada", "Lin"] };
var t2 = new Team { Members = t.Members.Add("Sam") };
Console.WriteLine(t.Members.Count + " " + t2.Members.Count); // 2 3

방어적 복사

변경 가능한 컬렉션을 받아야 한다면 입력 시 복사하여 외부의 변경 사항이 내부로 전달되지 않도록 하세요.

using System;
using System.Collections.Generic;
using System.Linq;

class Snapshot {
    private readonly int[] data;
    public Snapshot(IEnumerable<int> source) => data = source.ToArray();
    public IReadOnlyList<int> Data => data;
}

var list = new List<int> { 1, 2, 3 };
var snap = new Snapshot(list);
list.Add(4); // does not affect snap
Console.WriteLine(snap.Data.Count); // 3

값 동등성

변경 불가능한 개체에는 값 기반 동등성이 필요한 경우가 많습니다. 데이터가 같은 두 인스턴스를 같은 것으로 간주하는 방식입니다. 레코드는 이를 기본으로 제공하지만 클래스에서는 재정의가 필요합니다.

using System;

record Coord(int X, int Y);

Console.WriteLine(new Coord(1, 2) == new Coord(1, 2)); // True

별도 작업 없이 스레드 안전성 확보

변경 불가능한 개체는 절대 변경되지 않으므로 잠금 없이 공유해도 본질적으로 스레드 안전합니다.

using System;

class ReadonlyConfig {
    public required string Env { get; init; }
}

var cfg = new ReadonlyConfig { Env = "prod" };
// safe to read from many threads without synchronization
Console.WriteLine(cfg.Env); // prod

readonly 필드와 구조체

readonly 필드와 readonly struct를 사용하면 필드 수준에서 값 형식의 변경 불가능성을 강제할 수 있습니다.

using System;

readonly struct Vector {
    public readonly double X, Y;
    public Vector(double x, double y) { X = x; Y = y; }
    public double Length => Math.Sqrt(X * X + Y * Y);
}

Console.WriteLine(new Vector(3, 4).Length); // 5

함께 적용하기

required, 초기화, 값 동등성, 변경하지 않는 업데이트 메서드를 결합한 완전히 변경 불가능한 형식입니다.

using System;

record Account(string Id, decimal Balance) {
    public Account Deposit(decimal amount) => this with { Balance = Balance + amount };
}

var a = new Account("A1", 100m);
var b = a.Deposit(50m);
Console.WriteLine(a.Balance + " -> " + b.Balance); // 100 -> 150

빠른 확인

변경 불가능한 업데이트 원칙을 확인하세요.

요약

변경 불가능한 개체를 위한 패턴을 배웠습니다.

  • 필수 데이터에는 읽기 전용 또는 init 속성과 required를 사용하세요.
  • 변경을 새 인스턴스를 반환하는 메서드로 모델링하세요.
  • 변경 불가능하거나 방어적으로 복사한 컬렉션을 저장하세요.
  • 레코드는 값 동등성과 with 복사를 제공하며, 변경 불가능성은 스레드 안전성을 제공합니다.

자주 묻는 질문

“변경 불가능한 객체 패턴” 강의는 무료인가요?

네 — “변경 불가능한 객체 패턴” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C# Academy 강의 전체를 잠금 해제할 수 있습니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“변경 불가능한 객체 패턴”에서 뭘 배우나요?

생성 후 변경되지 않는 객체를 설계합니다. 브라우저에서 직접 실행하는 실습 코드로 C# Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

C# Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 C# Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“변경 불가능한 객체 패턴” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 C# Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 C# Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. init 전용 setter
  2. required 한정자
  3. 변경 불가능한 객체 패턴
  4. 레코드의 with 식
← C# Academy(으)로 돌아가기