C# 에서 

어떤 변수를 기존에 만든 객체로 할당하게 되면 해당 변수는 그냥 기존에 만들어진 객체를 참조하기 때문에 기존에 있던 객체와 같은 객체가 된다.


예시를 보면 쉽게 이해할 수 있다.


Ex)

public class Car
{
    public string Name;

    public string Color;
}

Car car1 = new Car{Name=“supercar”, Color=“red”};

Car car2 = car1;

car1.Name = “my supercar”;

라고 car1의 Name 을 변경했을 때

Console.WriteLine(car2.Name);

을 출력하면 my supercar 가 출력된다.

즉, car1과 car2는 같은 메모리 어드레스를 참조하는 변수인 것이다.


그렇다면 car1과 같은 value를 같는 새로운 객체를 만들고 싶다면 어떻게 해야할까?

Copy 와 관련된 메서드인 닷넷 프레임워크에서 제공해주는 Object 클래스의 MemberwiseClone 메서드를 이용해서 ShallowCopy() 메서드와 DeepCopy() 메서드를 만들어서 사용하면된다.

두 메서드 의 차이는 클래스가 참조형 멤버를 가지고 있을 때 참조형 멤버 객체를 새로 생성하는냐 생성하지 않느냐에 차이다.


일단 참조형 멤버를 가진 클래스를 만들어보자.

public class CarBrand
{
    public string Name;

    public string PhoneNum;
}

public class Car
{
    public string Name;

    public string Color;

    public CarBrand Brand; 

    public Car ShallowCopy()
    {
        return (Car)this.MemberwiseClone();
    {

    public Car DeepCopy()
    {
        Car other = (Car) this.MemberwiseClone();
        other.Brand = new CarBrand(Brand);
        other.Name = String.Copy(Name);
        other.Color = String.Copy(Color);
        return other;
    }
}

Car 라는 객체는 CarBrand라는 객체를 멤버로가지고 있다.


이제 우리가 만든 ShallowCopy 와 DeepCopy()를 예제 코드를 사용해서 비교해보자.

EX)
CarBrand carBrand = new CarBrand{Name=“Audi”, PhoneNum=“01012341234”};
Car car1 = new Car {Name=“a4”, Color=“white”, Brand=carBrand};

Car car2 = car1.ShallowCopy();
car2.Name = “sonata”;
car2.Brand = new CarBrand{Name=“Hyundai”, PhoneNum=“01012341234”};

로 하고 값을 확인해보면

car1의 Brand로 현대로 바뀐 것을 확인할 수 있다. Name 은 여전히 a4이다.

즉, Brand 객체를 같이 참조하고 있는 것을 확인 할 수 있다.



포함하고 있는 참조 객체까지 새롭게 만들고 싶다면 위에서 만든 DeepCopy() 함수를 이용하면 된다.

EX)
CarBrand carBrand = new CarBrand{Name=“Audi”, PhoneNum=“01012341234”};
Car car1 = new Car {Name=“a4”, Color=“white”, Brand=carBrand};

Car car2 = car1.ShallowCopy();
car2.Name = “sonata”;
car2.Brand = new CarBrand{Name=“Hyundai”, PhoneNum=“01012341234”};

로 하고 값을 확인해보면

car1의 Brand는 여전히 audi이고 car2의 Brand만 현대로 바뀐 것을 확인할 수 있다. 

즉, car2 에서 Brand 객체를 새롭게 만들어서 사용한것 을 확인할 수 있다.



위에서 살펴본 것 처럼 기본적으로 만들어진 객체를 이용해서 변수에 할당하게 되면 새로운 객체가 아니라 기존에 객체를 참조하게 되므로 shallowcopy나 deepcopy 같은 함수를 만들어서 사용해야 한다. 

shallowcopy와 deepcopy의 차이는 가지고 있는 멤버 중에 참조객체를 
새로 만드느냐 아니면 기존의 것을 같이 참조하냐의 차이다.







+ Recent posts