먼저 얕은 복사로 리스트를 복사하는 방법을 설명합니다. 그리고 얕은 복사로 문제가 발생할 수 있는 상황과 깊은 복사로 해결하는 방법에 대해서 알아보겠습니다.
1. 리스트 복사 (얕은 복사)
얕은 복사로 리스트를 복사하는 방법을 소개합니다.
1.1 List 생성자를 이용한 방법
아래 예제와 같이 new List<string>(list)
으로 리스트를 생성할 때 인자로 리스트를 전달하여 복사할 수 있습니다.
using System;
namespace Example {
public class Program {
public static void Main(string[] args) {
List<string> list = new List<string>() {"a", "b", "c", "d"};
List<string> copy = new List<string>(list);
Console.WriteLine(string.Join(", ", list));
Console.WriteLine(string.Join(", ", copy));
}
}
}
Output:
a, b, c, d
a, b, c, d
1.2 List.ToList()를 이용한 방법
list.ToList()
는 복사된 리스트를 리턴합니다.
List<string> list = new List<string>() {"a", "b", "c", "d"};
List<string> copy = list.ToList();
Console.WriteLine(string.Join(", ", list));
Console.WriteLine(string.Join(", ", copy));
Output:
a, b, c, d
a, b, c, d
1.3 List.GetRange()를 이용한 방법
list.GetRange(index, count)
는 리스트의 index에서 count 개수만큼의 요소를 새로운 리스트에 추가하여 리턴합니다.
아래와 같이 GetRange()
로 리스트를 복사할 수 있습니다.
List<string> list = new List<string>() {"a", "b", "c", "d"};
List<string> copy = list.GetRange(0, list.Count);
Console.WriteLine(string.Join(", ", list));
Console.WriteLine(string.Join(", ", copy));
Output:
a, b, c, d
a, b, c, d
2. 얕은 복사로 발생하는 문제
string, int 같은 기본 자료형이 아니고, 클래스 객체를 갖고 있는 리스트일 때 얕은 복사를 사용했을 때 문제가 될 수 있습니다.
예를 들어, 아래 예제는
Person
객체의 리스트를 얕은 복사로 복사합니다.- 복사된 리스트에서
Index 0
의Person
객체의age
를 0으로 변경합니다. - 원본 리스트와 복사된 리스트의 내용을 확인해보면, 둘다
John
의age
가 0으로 변경되었습니다.
앝은 복사는 리스트가 객체 정보만 복사하여 참조하기 때문에, 객체 안의 데이터는 복사되지 않고 두개의 리스트가 함께 참조하게 됩니다. 이 데이터가 변경되면 원본 리스트와 복사본 리스트가 참조하는 객체 정보가 함께 변경됩니다.
using System;
namespace Example {
public class Person {
public string name;
public int age;
public Person(string name, int age) {
this.name = name;
this.age = age;
}
public override string ToString() {
return "[" + name + ", " + age + "]";
}
}
public class Program {
public static void Main(string[] args) {
List<Person> list = new List<Person>();
list.Add(new Person("John", 30));
list.Add(new Person("Patrick", 34));
list.Add(new Person("Doe", 22));
List<Person> copy = new List<Person>(list);
copy.ElementAt(0).age = 0;
Console.WriteLine(string.Join(", ", list));
Console.WriteLine(string.Join(", ", copy));
}
}
}
Output:
[John, 0], [Patrick, 34], [Doe, 22]
[John, 0], [Patrick, 34], [Doe, 22]
3. 리스트 복사 (깊은 복사)
List.ConvertAll(converter)
는 리스트의 요소를 converter
를 사용하여 다른 데이터로 변경하는 함수입니다.
리스트의 모든 요소에 대해서 아래와 같이 Person
객체를 재생성하여 리턴하면, 객체 자체를 복사한 리스트가 생성됩니다.
ConvertAll(p => new Person(p.name, p.age))
객체 자체를 복사하였기 때문에, 원본 리스트와 복사된 리스트는 서로 다른 객체를 갖고 있으며, 아래와 같이 특정 요소의 값을 변경해도 다른 리스트에 영향을 주지 않게 됩니다.
using System;
namespace Example {
public class Person {
public string name;
public int age;
public Person(string name, int age) {
this.name = name;
this.age = age;
}
public override string ToString() {
return "[" + name + ", " + age + "]";
}
}
public class Program {
public static void Main(string[] args) {
List<Person> list = new List<Person>();
list.Add(new Person("John", 30));
list.Add(new Person("Patrick", 34));
list.Add(new Person("Doe", 22));
List<Person> copy = list.ConvertAll(
p => new Person(p.name, p.age));
copy.ElementAt(0).age = 0;
Console.WriteLine(string.Join(", ", list));
Console.WriteLine(string.Join(", ", copy));
}
}
}
Output:
[John, 30], [Patrick, 34], [Doe, 22]
[John, 0], [Patrick, 34], [Doe, 22]
Related Posts
- C# 바이트(Byte) 배열을 문자열로 변환
- C# String.format() 함수 알아보기
- C# - foreach (Array, List, Dictionary)
- C# 프로퍼티(Property) Get/Set 함수
- C# - Dictionary에서 key, value 가져오기
- C# - Dictionary 순회, foreach, for 루프
- C# - Dictionary에서 key, value 삭제
- C# - Dictionary.add()로 데이터 추가
- C# - Dictionary 선언 및 초기화
- C# - 문자열을 Double, Float으로 변환
- C# - 문자열을 리스트로 변환
- C# - 두 날짜/시간 비교, DateTime.Compare()
- C# - 날짜 계산, DateTime 시간 더하기 빼기
- C# - 날짜 문자열을 DateTime으로 변환
- C# - Sleep, 몇 초간 지연시키기
- C# - Timestamp(millisecond)를 DateTime 객체로 변환
- C# - 현재 시간 가져오기, DateTime
- C# - 문자열 리스트를 문자열로 변환
- C# - 리스트 복사 (얕은 복사, 깊은 복사)
- C# - 2차원 리스트 선언 및 초기화
- C# - 리스트 선언 및 초기화
- C# - 리스트 길이, 크기 가져오기
- C# - 리스트 합계, 평균 계산
- C# - 리스트 요소 제거 (RemoveAt, RemoveAt, RemoveAll)
- C# - 리스트에서 빈 문자열, null 제거
- C# - 리스트 두개로 분리, n개로 나누기
- C# - 문자열 뒤집기, Reverse()
- C# - 2차원 배열 복사, Clone
- C# - 문자열 배열을 문자열로 변환
- C# - 2차원 배열 선언, 초기화 방법
- C# - 배열 길이, 2차원 배열 길이
- C# - 두개의 배열을 하나로 합치기
- C# - 배열 중복 요소 제거
- C# - 배열에서 특정 요소 제거
- C# - Int 배열 정렬 (오름차순, 내림차순)