C#에서 ArrayList의 얕은 복사본(shallow copy)을 만들려면 Clone() 메서드를 사용하면 됩니다. Clone() 메서드는 ArrayList의 구조와 요소 목록을 그대로 복제한 새로운 ArrayList를 반환하며, 반환 타입이 object이므로 사용 시 (ArrayList)로 명시적 캐스팅이 필요합니다.
ArrayList의 얕은 복사본이란?
얕은 복사본은 원본 컬렉션의 요소 구성(개수, 순서)만 새롭게 복제하는 방식입니다. 이때 컬렉션에 저장된 개별 요소 자체를 깊게 복사(deep copy)하지 않고 원본과 동일한 참조를 공유합니다. 문자열이나 숫자 같은 값처럼 다뤄지는 데이터는 사실상 독립된 복사본처럼 동작하지만, 참조 형식 객체가 저장된 경우 복사본과 원본이 같은 객체를 가리키게 되므로 주의가 필요합니다.
예제 1: Clone() 메서드로 ArrayList 복제하기
다음 예제에서는 ArrayList에 여러 요소를 추가한 뒤, Insert()로 중간에 새 요소를 삽입하고 Clone()으로 복제하는 과정을 보여줍니다.
using System;
using System.Collections;
public class Demo {
public static void Main(){
ArrayList list = new ArrayList();
list.Add("One");
list.Add("Two");
list.Add("Three");
list.Add("Four");
list.Add("Five");
list.Add("Six");
list.Add("Seven");
list.Add("Eight");
Console.WriteLine("ArrayList elements...");
foreach(string str in list){
Console.WriteLine(str);
}
Console.WriteLine("ArrayList is read-only? = "+list.IsReadOnly);
Console.WriteLine("Does the element Six in the ArrayList? = "+list.Contains("Six"));
list.Insert(4, "Twelve");
Console.WriteLine("
ArrayList elements...UPDATED");
foreach(string str in list){
Console.WriteLine(str);
}
ArrayList list2 = new ArrayList();
list2 = (ArrayList)list.Clone();
Console.WriteLine("
Cloned ArrayList...");
foreach(string str in list2){
Console.WriteLine(str);
}
}
}출력 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
ArrayList elements... One Two Three Four Five Six Seven Eight ArrayList is read-only? = False Does the element Six in the ArrayList? = True ArrayList elements...UPDATED One Two Three Four Twelve Five Six Seven Eight Cloned ArrayList... One Two Three Four Twelve Five Six Seven Eight
출력 결과에서 확인할 수 있듯이, Clone() 호출 시점의 list 상태(“Twelve”가 삽입된 상태)가 그대로 list2에 복제되었습니다.
예제 2: 요소 제거 후 복제하기
이번에는 ArrayList에서 Remove() 메서드로 특정 요소를 제거한 뒤, 변경된 상태를 Clone()으로 복제하는 예제를 살펴보겠습니다.
using System;
using System.Collections;
public class Demo {
public static void Main(String[] args){
ArrayList list1 = new ArrayList();
list1.Add("A");
list1.Add("B");
list1.Add("C");
list1.Add("D");
list1.Add("E");
list1.Add("F");
list1.Add("G");
list1.Add("H");
list1.Add("I");
Console.WriteLine("Elements in ArrayList1...");
foreach (string res in list1){
Console.WriteLine(res);
}
ArrayList list2 = new ArrayList();
list2.Add("A");
list2.Add("B");
list2.Add("C");
list2.Add("D");
list2.Add("E");
list2.Add("F");
list2.Add("G");
list2.Add("H");
list2.Add("I");
list2.Add("G");
list2.Add("I");
Console.WriteLine("Elements in ArrayList2...");
foreach (string res in list2){
Console.WriteLine(res);
}
Console.WriteLine("Count of elements in ArrayList2 = " + list2.Count);
list2.Remove("G");
Console.WriteLine("Elements in ArrayList2... (UPDATED)");
foreach (string res in list2){
Console.WriteLine(res);
}
Console.WriteLine("Count of elements in ArrayList2 (Updated) = " + list2.Count);
ArrayList list3 = new ArrayList();
list3 = (ArrayList)list2.Clone();
Console.WriteLine("
Cloned ArrayList from ArrayList2...");
foreach(string str in list3){
Console.WriteLine(str);
}
}
}출력 결과
실행 결과는 다음과 같습니다.
Elements in ArrayList1... A B C D E F G H I Elements in ArrayList2... A B C D E F G H I G I Count of elements in ArrayList2 = 11 Elements in ArrayList2... (UPDATED) A B C D E F H I G I Count of elements in ArrayList2 (Updated) = 10 Cloned ArrayList from ArrayList2... A B C D E F H I G I
Remove("G")는 맨 처음 발견된 “G” 하나만 제거하며, 나머지 “G”와 “I”는 그대로 유지됩니다. 이후 Clone()을 호출하면 제거 작업이 반영된 최신 상태가 list3에 복제된 것을 확인할 수 있습니다.
핵심 정리
- Clone() 메서드를 사용하면 ArrayList의 얕은 복사본을 손쉽게 만들 수 있습니다.
- 반환 타입이 object이므로 (ArrayList) 캐스팅이 반드시 필요합니다.
- 얕은 복사본은 요소의 참조를 공유하므로, 참조 형식 객체를 담고 있는 경우 복사본 수정이 원본에 영향을 줄 수 있습니다.
- 완전히 독립적인 복사본이 필요하다면 직접 순회하며 새 ArrayList에 요소를 추가하는 방식이나 직렬화 기반의 깊은 복사를 고려해야 합니다.