C#에서 객체를 복사하는 방법은 크게 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy) 두 가지로 나눌 수 있습니다. 두 방식은 복사의 범위와 결과가 완전히 다르기 때문에, 그 차이를 정확히 이해하는 것이 매우 중요합니다.
얕은 복사(Shallow Copy)란?
얕은 복사는 객체를 복사할 때 객체 자체만 복사하고, 그 안에 포함된 내부 객체까지는 복사하지 않는 방식입니다.
즉, 내부 객체는 원본 객체와 복사본이 서로 공유하게 됩니다.
얕은 복사의 가장 큰 문제점은 두 객체가 완전히 독립적이지 않다는 점입니다. 따라서 한쪽 객체에서 값을 수정하면, 그 변경 사항이 다른 객체에도 그대로 반영됩니다.
깊은 복사(Deep Copy)란?
깊은 복사는 객체의 전체 구조를 통째로 복사하여 완전히 독립적인 복사본을 만드는 방식입니다.
복사가 완료된 후에는 두 객체가 서로에게 영향을 주지 않기 때문에, 한쪽에서 값을 수정하더라도 다른 쪽 객체에는 아무런 변화가 발생하지 않습니다.
C# 예제 코드
class Program{
static void Main(string[] args){
// 얕은 복사 (Shallow Copy)
ShallowCopy obj = new ShallowCopy();
obj.a = 10;
ShallowCopy obj1 = new ShallowCopy();
obj1 = obj;
Console.WriteLine("{0} {1}", obj1.a, obj.a); // 10 10
obj1.a = 5;
Console.WriteLine("{0} {1}", obj1.a, obj.a); // 5 5
// 깊은 복사 (Deep Copy)
DeepCopy d = new DeepCopy();
d.a = 10;
DeepCopy d1 = new DeepCopy();
d1.a = d.a;
Console.WriteLine("{0} {1}", d1.a, d.a); // 10 10
d1.a = 5;
Console.WriteLine("{0} {1}", d1.a, d.a); // 5 10
Console.ReadLine();
}
}
class ShallowCopy{
public int a = 10;
}
class DeepCopy{
public int a = 10;
}
실행 결과
10 10 5 5 10 10 5 10
결과 분석
얕은 복사의 경우
obj1 = obj; 코드는 새로운 객체를 만드는 것이 아니라, obj가 참조하고 있는 동일한 객체의 주소를 복사하는 것입니다. 결국 obj와 obj1은 같은 객체를 가리키게 되므로, obj1.a = 5;로 값을 변경하면 obj.a의 값도 함께 5로 바뀌어 5 5가 출력됩니다.
깊은 복사의 경우
d1.a = d.a; 코드는 값 자체를 복사하기 때문에 d와 d1은 서로 독립적입니다. 따라서 d1.a = 5;로 값을 변경해도 d.a는 여전히 10으로 유지되어 5 10이 출력됩니다.
얕은 복사 vs 깊은 복사 비교 정리
| 구분 | 얕은 복사 (Shallow Copy) | 깊은 복사 (Deep Copy) |
|---|---|---|
| 복사 범위 | 객체의 참조(주소)만 복사 | 객체와 내부 데이터 전체를 복사 |
| 내부 객체 | 원본과 공유됨 | 새로 생성되어 완전히 독립적 |
| 수정 시 영향 | 한쪽 수정 시 다른 쪽에도 반영됨 | 서로에게 영향을 주지 않음 |
| 독립성 | 낮음 | 높음 |
정리하면, 얕은 복사는 메모리 사용 측면에서 효율적이지만 데이터 독립성이 보장되지 않으며, 깊은 복사는 약간 더 많은 비용이 들지만 원본과 복사본을 완전히 분리할 수 있다는 장점이 있습니다. 상황에 맞게 적절한 복사 방식을 선택하는 것이 안전한 C# 프로그래밍의 핵심입니다.