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만의 힙 메모리 영역을 가지는 객체가 되었습니다.
상단에서 “참조 형식은 스택 메모리 영역에 할당되고 값 형식은 힙 메모리 영역에 할당됩니다.”라고 하셨는데 참조 형식은 힙 영역에 저장되고 값 형식이 스택 메모리 영역에 할당으로 수정해야할 것 같네요
수정하였습니다. 감사합니다 🙂
잘봤습니다 덕분에 개발에 도움이 많이 되었습니다!