본문 바로가기
프로그래밍/C#

C# 얕은 복사, 깊은 복사에 대해서 알아보자

by bantomak 2025. 5. 19.
반응형

얕은 복사(Shallow Copy) 예시 코드

  • Key와 Value가 그대로 복사됨
  • Value가 만약 참조 타입이면, 복사본과 원본이 같은 인스턴스를 가리킴
Dictionary<string, Currency> Currencies = new()
{
    { "USD", new Currency("Dollar", 1.0m) },
    { "EUR", new Currency("Euro", 0.9m) }
};

var shallowCopy = Currencies.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

깊은 복사(Deep Copy) 예시 코드

Dictionary<string, Currency> Currencies = new()
{
    { "USD", new Currency("Dollar", 1.0m) },
    { "EUR", new Currency("Euro", 0.9m) }
};

var deepCopy = Currencies.ToDictionary(
    kvp => kvp.Key,              // 그대로 키 복사
    kvp => kvp.Value.Clone());   // 값을 Clone() 해서 복사 (깊은 복사)
  • ToDictionary(...) : 원본 Currencies 딕셔너리를 새 딕셔너리로 복사
  • kvp.Key : 키는 그대로 사용 (string이므로 불변)
  • kvp.Value.Conle() : 값 객체를 복제하여 원본과 분리된 인스턴스를 생성

왜 Clone()을 쓰는가?

  • 얕은 복사(shallow copy)를 하면 새 딕셔너리가 같은 객체를 참조로 가리킴
  • 즉, 복사본을 수정하면 원본도 바뀌어 버림
var copy = original.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); // 얕은 복사
copy["USD"].Rate = 999; // 원본도 같이 바뀜

예제 구현 코드

public class Currency
{
    public string Name { get; set; }
    public decimal Rate { get; set; }

    public Currency(string name, decimal rate)
    {
        Name = name;
        Rate = rate;
    }

    public Currency Clone()
    {
        return new Currency(Name, Rate); // 새 인스턴스로 복사
    }
}

정리하자면

  • Currencies.ToDictionary(...) : 딕셔너리 복제
  • kvp.Key : 키는 그대로 복사 (string은 불변이라 안전)
  • kvp.Value.Clone() : 값은 깊은 복사 (참조 공유 방지)
  • 이는 원본을 변경하지 않고 안전하게 복사하기 위한 깊은 복사 방식

함께 읽으면 좋은 글

 

C# String은 참조 타입(Reference type)이면서 불변(Immutable)하다.

string vs StringBuilder 예를 들어, int의 경우를 살펴보자. int는 값 타입(value type)이면서 가변(mutable)이다. 값 타입은 데이터 변경 시에 새로운 메모리 할당이 일어나지 않는다. 이미 생성된 메모리의

jettstream.tistory.com

댓글