불변 ( Immutable )

2025. 11. 14. 20:23·⭐C Sharp/11. 객체 지향

불변 ( Immutable )

프로그래밍을 하다 보면 한 번 만들어진 데이터가 절대 바뀌지 않는 경우들을 보게 된다.

문자열을 조작하려고 했는데 원본이 그대로인 경우가 발생하는데 이런 현상이 바로 불변 특성 때문이다

 

 

정의

불변은 "한 번 생성된 객체의 상태가 절대 변경되지 않는다" 는 특성이다.

객체가 만들어진 후에는 내부 데이터를 수정할 수 없고 , 수정하려고 하면 새로운 객체가 생성된다.

대표적인 불편 타입으로는 string , delegate 그리고 대부분의 값 타입들이 있다.

 

 

 

예시 코드

string original = "HoChan";
string modified = original + " Blog";

Console.WriteLine(original); // "HoChan" (원본 그대로)
Console.WriteLine(modified); // "HoChan Blog" (새로운 문자열)

 

여기서 + 연산을 했다고 해서 original 이 바뀌는 것이 아니다.

새로운 문자열 객체가 만들어져서 modified 에 할당된 것이다.

string msg = "Ho";
msg += "Chan";

Console.WriteLine(msg); 
// 출력: HoChan

겉으로 보기에는 msg가 수정된 것처럼 보인다.

실제로는 이렇게 돌아간다

  • "Chan" 이라는 새로운 문자열이 Heap 에 생성된다
  • msg 변수가 새로운 문자열을 참조하게 된다
  • 기존 "Ho" 문자열은 GC 컬렉션의 대상이 된다

 

기업 면접에서 자주 나오는 문제가 있다.

internal class Program
{
    static void Main(string[] args)
    {
        string a = "안녕";
        string b = a;

        b = "하세요";

        Console.WriteLine(a + b);
    }
}

정답을 바로 말하면 "안녕하세요" 가 출력된다.

핵심 개념 : string 은 불변 ( Immutable )

  • string b = a; → a 와 b 는 같은 문자열 객체 "안녕"을 참조한다
  • 하지만 불변이므로 값을 "수정"하는 것이 불가능하다
  • b = "하세요"; → 기존 문자열을 바꾸는 것이 아니라
    └ b 가 새로운 문자열 객체를 참조하도록 변경된다

 

a → 여전히 "안녕"

b → "하세요" 새 객체

 

 

delegate 의 불변 특성

델리게이트도 불변 객체이다.

델리게이트에 함수를 추가하거나 제거할 때에도 기존 델리게이트가 바뀌는 것이 아니라 새로운 델리게이트가 생성된다.

Action printMessage = () => Console.WriteLine("Hello");
Action original = printMessage;

printMessage += () => Console.WriteLine("World");

printMessage();
original();
  • += 연산으로 함수를 추가했지만 , original 과 printMessage 는 서로 다른 델리게이트 객체를 참조하고 있다

 

▼ printMessage 호출 시

Hello
World

 

▼original 호출 시

Hello

 

 

  • original = printMessage; 할 때
    original 은 딱 "Hello" 한 개만 들어있는 델리게이트를 가리킨다
  • printMessage += ... 는 printMessage 에 새로운 델리게이트를 추가한 것처럼 보이지만
    사실상 새로운 델리게이트 객체를 만들어서 printMessage 에 다시 대입한 것이다

 

 

불변 특성의 장점

1. 예측 가능성 증가 ( 버그 크게 감소 )

값이 중간에 몰래 바뀌는 일이 없다

그러므로 디버깅 스트레스가 크게 줄어든다

코드 흐름이 명확해져 유지보수가 쉽다

 

2. 쓰레드 안전 ( Thread - Safe )

읽기만 가능해서 여러 쓰레드가 동시에 접근해도 안전하다

동기화 ( lock ) 절차가 줄어들어 멀티쓰레드 환경에서 매우 유리하다

 

3. 해시 코드 안정성

Dictionary<TKey , TValue> 의 키로 사용할 때 안전하다

 

4. 참조 공유가 안전하다

가변 객체는 여러 곳에서 같은 객체를 참조하면 한 곳의 수정이 전체에 영향

불변 객체는 수정이 불가능해서 이런 문제가 없다.

 

 

불변 특성의 단점

1. 자주 변경하는 경우 오히려 비효율적이다

값 변경은 새로운 객체를 생성한다

문자열을 계속 누적하는 경우 매번 새 객체를 생성해야 한다

이 때문에 StringBuilder 가 필요하다

 

2. 메모리 사용량 증가 가능

변경이 필요할 때마다 새 객체를 생성한다. 특히 큰 객체라면 비효율이다

빈번한 문자열 조작 시 많은 임시 객체를 생성한다

GC 압박 증가 가능성이 커지고 성능 저하로 이어진다

 

 

해결 방법 : StringBuilder

문자열을 자주 수정해야 한다면 StringBuilder 를 사용하는 것이 좋다

StringBuilder sb = new StringBuilder();
sb.Append("Hello");
sb.Append(" ");
sb.Append("World");
string result = sb.ToString();

 

 

 

정리

  • 불변은 안정성, 예측 가능성, 쓰레드 안전성이 매우 뛰어나다.
  • 하지만 변경이 많은 환경에서는 오히려 성능이 떨어지고 객체 생성이 많아진다.
  • 안정성이 필요한 영역은 불변 / 성능, 변경 빈도가 높으면 가변을 선택하면 된다.

 

 

참고 자료

https://learn.microsoft.com/ko-kr/dotnet/api/system.text.stringbuilder?view=net-10.0

 

'⭐C Sharp > 11. 객체 지향' 카테고리의 다른 글

sealed class  (0) 2025.10.09
virtual 과 override  (0) 2025.10.08
readonly  (0) 2025.10.02
상속 ( OOP )  (0) 2025.09.28
추상 클래스 ( Abstract Class )  (0) 2025.09.28
'⭐C Sharp/11. 객체 지향' 카테고리의 다른 글
  • sealed class
  • virtual 과 override
  • readonly
  • 상속 ( OOP )
DevHoChan
DevHoChan
맨땅에서 시작하는 코딩 도전
  • DevHoChan
    Debugging Life
    DevHoChan
  • 전체
    오늘
    어제
    • 분류 전체보기 (374)
      • 🕹️Game Life (1)
      • 🖥️Computer Science (5)
      • 📖TIL (141)
        • 🔥Projects (16)
        • 💡DevTips (5)
        • 🤔발생한 문제와 해결 (5)
        • 🔮Unity Graphics (5)
        • 🎤Interview (3)
        • ✅CodingTest (9)
      • 🚀Game Release (4)
      • 🧊Unity Basic (58)
        • 📌용어 사전 (1)
        • 에디터&인터페이스 (3)
        • 디버그 (1)
        • 라이프사이클 (4)
        • 게임오브젝트 (4)
        • 프리팹 (1)
        • 오브젝트풀링 (4)
        • 애트리뷰트 (2)
        • 트랜스폼 (4)
        • 물리&충돌 (1)
        • 프레임&델타타임 (4)
        • 코루틴&이벤트 (7)
        • 수학&보정함수 (3)
        • 디자인패턴 (9)
        • UGUI (3)
        • 벡터 ( Vector ) (3)
        • 씬 ( Scene ) (2)
        • 데이터 관리 (2)
      • ⭐C Sharp (99)
        • 📌용어 사전 (1)
        • 📌문법 사전 (6)
        • 메모리 관리 (3)
        • 00. 문법 (17)
        • 01. 변수 (3)
        • 02. 자료형 (2)
        • 03. 연산자 (6)
        • 04. 조건문 (2)
        • 05. 반복문 (2)
        • 06. 배열 (3)
        • 07. 메서드(함수) (7)
        • 08. 열거형 (3)
        • 09. 구조체 (2)
        • 10. 참조 (2)
        • 11. 객체 지향 (11)
        • 12. 델리게이트 (3)
        • 13. 디자인 패턴 (7)
        • 14. LINQ (1)
        • 📂▼자료구조 (2)
        • 15-1. 제네릭 (3)
        • 15-2. 배열 (4)
        • 15-3. 리스트 (2)
        • 15-4. 스택과 큐 (2)
        • 15-5. 딕셔너리 해시테이블 (2)
        • 15-6. 트리와 그래프 (3)
      • 📊Algorithm (16)
        • BigO (2)
        • 정렬 (4)
        • 셔플 (2)
        • 탐색 (6)
        • 최적화 (1)
      • 📝Game Design (16)
      • 🤖​AI Tools (12)
        • AI 리뷰 분석 (6)
        • Player2 (0)
        • 3D 모델링 (1)
        • 2D 스프라이트 (0)
        • 이미지 (2)
        • 사운드 (1)
        • 동영상 (1)
        • 문서 (1)
      • 🌍Network (6)
      • 🌱Github (11)
        • 기본 개념 (7)
        • 명령어 (1)
        • 도구 활용 (1)
      • ⚙️Visual Studio (5)
        • 🔧설치 및 환경설정 (2)
        • ⌨️HotKey (1)
        • 🚨디버깅 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    자료구조
    csharp
    디자인패턴
    c#
    게임디자인
    메모리관리
    CodingTest
    객체지향
    기획
    algorithm
    부트캠프
    unity
    게임기획
    gamedesign
    자료형
    문법
    til
    유니티
    OOP
    GitHub
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
DevHoChan
불변 ( Immutable )
상단으로

티스토리툴바