Posted in: C# 언어

C# 객체 복사하기: 얕은 복사와 깊은 복사

C#은 메모리에 저장되는 방식에 따라 참조 형식과 값 형식이 있습니다.

값 형식은 변수가 값을 담는 데이터 형식을 말하고, 참조 형식은 변수의 값 대신 값이 있는 곳의 위치(참조)를 담는 데이터 형식을 말합니다.

값 형식은 스택 메모리 영역에 할당되고 참조 형식은 힙 메모리 영역에 할당됩니다.

얕은 복사와 깊은 복사를 알기전에 위 내용을 먼저 숙지해야 합니다.

얕은 복사


객체를 복사할 때 참조만 복사하는 것을 얕은 복사(Shallow Copy)라고 합니다.

class MyClass
{
    public int MyField1;
    Public int MyField2;
}

static void Main(string[] args)
{
    MyClass source = new MyClass();
    source.MyField1 = 10;
    source.MyField2 = 20;

    MyClass target = source;
    target.MyField2 = 30;

    Console.WriteLine($"{source.MyField1} {source.MyField2}");
    Console.WriteLine($"{target.MyField1} {target.MyField2}");
}
출력 결과

10 30
10 30

클래스는 태생이 참조 형식이기 때문에 위 코드처럼 클래스를 복사하면 똑같은 힙 메모리 영역을 가리키게 됩니다. 때문에 target의 MyField2를 바꾸면 source의 MyField2도 바뀝니다.

깊은 복사


객체를 복사할 때 별도의 힙 메모리 영역에 할당하는 것을 깊은 복사(Deep Copy)라고 합니다.

class MyClass
{
    public int MyField1;
    Public int MyField2;

    public MyClass DeepCopy()
    {
        MyClass newCopy = new MyClass();
        newCopy.MyField1 = this.MyField1;
        newCopy.MyField2 = this.MyField2;
        return newCopy;
    }
}

static void Main(string[] args)
{
    MyClass source = new MyClass();
    source.MyField1 = 10;
    source.MyField2 = 20;

    MyClass target = source.DeepCopy();
    target.MyField2 = 30;

    Console.WriteLine($"{source.MyField1} {source.MyField2}");
    Console.WriteLine($"{target.MyField1} {target.MyField2}");
}
출력 결과

10 20
10 30

DeepCopy() 메소드에서 새로운 MyClass 변수를 선언하고 변수값을 저장하여 반환하기 때문에 source의 변수값을 정상적으로 복사받고 target만의 힙 메모리 영역을 가지는 객체가 되었습니다.

Comments (2) on "C# 객체 복사하기: 얕은 복사와 깊은 복사"

  1. 상단에서 “참조 형식은 스택 메모리 영역에 할당되고 값 형식은 힙 메모리 영역에 할당됩니다.”라고 하셨는데 참조 형식은 힙 영역에 저장되고 값 형식이 스택 메모리 영역에 할당으로 수정해야할 것 같네요

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다