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

C# 얕은 복사(Shallow Copy), 깊은 복사(Deep Copy)

by bantomak 2023. 1. 18.

얕은 복사, 깊은 복사에 대해서

얕은 복사(Deep Copy)

 

class Point
{
    public int x;
    public int y;

    public Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public override string ToString()
    {
        return $"{x}, {y}";
    }
    
    public Point DeepCopy()
    {
        return new Point(x, y);
    }
}
class Program
{
    static void Main(string[] args)
    {
        Point A = new Point(1, 2);
        Point B = A;

        B.x = 5;

        Console.WriteLine("Point A :" + A.ToString());
        Console.WriteLine("Point B :" + B.ToString());

        // Point A :5, 2
        // Point B :5, 2
    }
}

B 객체를 생성시에 A를 대입해서 생성하였더니 B 객체를 수정하면 A객체에도 동시에 적용됩니다.

이를 얕은 복사(Shallow Copy)라고 합니다.

 

그렇다면 이번에는 완전히 독립적인 객체를 생성해보겠습니다.

 

깊은 복사(Shallow Copy)

 

class Program
{
    static void Main(string[] args)
    {
        Point A = new Point(1, 2);
        Point B = A.DeepCopy();

        B.x = 5;

        Console.WriteLine("Point A :" + A.ToString());
        Console.WriteLine("Point B :" + B.ToString());

        // Point A :1, 2
        // Point B :5, 2
    }
}

B 객체를 생성시에 DeepCopy 함수로 생성했더니 완전히 독립적인 객체로 생성이 되었습니다.

 


Class가 아닌 경우

 

class Temp
{
    public int value;

    public Temp(int value)
    {
        this.value = value;
    }

    public int Value
    {
        get { return this.value; }
        set { this.value = value; }
    }
}

class Program
{
    static void Main(string[] args)
    {
        // shallow copy
        var array = new Temp[3];
        array[0] = new Temp(0);
        array[1] = new Temp(0);
        array[2] = new Temp(0);

        var newArray = array.ToArray();
        newArray[1].Value = 5;

        Console.WriteLine("Shallow Copy :");

        // newArray를 변경했지만 변경내역이 array에도 반영됨
        foreach (var element in array)
        {
            Console.WriteLine(element.Value);
        }

        Console.WriteLine("Deep Copy :");

        // deep copy
        var intArray = new int[3] { 0, 0, 0 };
        var newArray2 = intArray.ToArray();
        newArray2[1] = 5;

        // newArray2를 변경했지만 변경내역이 intArray에 반영되지 않음
        foreach (var element in intArray)
        {
            Console.WriteLine(element);
        }
    }
}

 

참조 타입(Reference Type)인 Class배열을 ToArray() 호출하면 얕은 복사가 이뤄진다.

하지만 값 타입(Value Type) Int배열 ToArray()를 호출하면 깊은 복사가 이뤄진다.

 

함께 읽으면 좋은 글

 

프로토타입(Prototype) 패턴

🤔문제객체가 있고 그 객체의 정확한 복사본을 만들고 싶다고 가정하면, 어떻게 해야 할까?먼저 같은 클래스의 새 객체를 생성해야 한다. 그런 다음 원본 객체의 모든 필드들을 살펴본 후 해당

jettstream.tistory.com

'프로그래밍 > C#' 카테고리의 다른 글

C# 간단하게 Json 형식 파싱하기  (2) 2023.01.26
C# 연산자(Operators)  (0) 2023.01.25
C# 가변(Mutable)과 불변(Immutable) 타입에 대하여  (0) 2023.01.25
C# 비트 연산자  (0) 2023.01.15
C#의 역사  (0) 2023.01.03

댓글