| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- multi-thread
- git
- PS
- 독서
- Network Programming
- System Programming
- Online Judge
- c#
- Data Structure
- Toy Project
- C++
- Unity
- BOJ
- Today
- Total
I'm FanJae.
[20260512] C# ( List ) 본문
1. List
(1) 정의
- List<T>는 C#의 제네릭 기반 동적 배열 클래스이다.
- 배열처럼 인덱스로 접근할 수 있으며, 필요할 때 내부 크기가 자동으로 증가한다.
List<int> scores = new List<int>();
scores.Add(90);
scores.Add(85);
scores.Add(100);
Console.WriteLine(scores[0]);
- 하지만 배열과 달리 처음부터 크기를 정확하게 정할 필요는 없다.
(2) 기존 배열(Array)의 문제점
int[] scores = new int[3];
scores[0] = 90;
scores[1] = 85;
scores[2] = 100;
// scores[3] = 70; // IndexOutOfRangeException이 발생
- 기존 배열은 배열의 크기를 초과하면 오류가 발생한다.
- 위 코드는 IndexOutOfRnageException 이 발생한다.
- 배열 크기를 늘리려면 새로운 배열을 만들어야 한다.
int [] newSocres = new int[4];
for(int i = 0; i < socres.Length; i++)
{
newScores[i] = scores[i];
}
newSocres[3] = 70;
scores = newScores;
① 배열의 문제점
- 배열의 크기를 중간에 변경하기 어렵다.
- 크기를 늘릴 때 마다 새로운 배열의 생성 및 기존 데이터 복사가 필요하다.
- 데이터가 많아질수록 복사 비용도 증가한다.
(3) ArrayList
- List<T> 가 나오기 전에 사용했다.
- 배열처럼 동작하지만, 크기가 자동으로 증가하눈 구조였다.
ArrayList list = new ArrayList();
list.Add(90);
list.Add(100);
list.Add(200);
- 형태만 보면 배열과 크게 다르지 않았다.
① 장점
- 어떤 타입이든 제약을 받지 않고 넣을 수 있다.
- 크기를 자동으로 늘려준다.
② ArrayList의 문제점
- 아무 타입이나 다 들어간다.
- 타입 안정성이 없다.
ArrayList list = new ArrayList();
list.Add(90);
list.Add("FanJae");
list.Add(3.14f);
// int, float, string 모든 타입이 다 들어가고 있다.
- int, float, string 모든 타입이 다 들어가고 있다.
foreach(object obj in list)
{
int score = (int)obj;
}
- 위와 같은 작업을 진행하면 런타임에서 예외가 발생한다.
- 위와 같이 값 형식을 참조 형식으로 변환 또는 반대 작업은 권장되는 작업이 아니다. (이 문제에 대해서는 박싱 & 언박싱 문제에서 다룬다.)
(4) List<T>
- 위와 같은 문제를 해결하기 위해 많이 사용하는 것이 List<T> 이다.
List<int> list = new List<int>();
list.Add(90);
list.Add(100);
list.Add(200);
- List<int>는 int만 저장 가능하다.
list.Add("FanJae");
- 위 코드는 컴파일 오류가 발생한다.
- 즉, 잘못된 타입이 들어오는 것을 미리 막아준다.
(5) List의 특징
① 제네릭 기반
- List<T> 는 제네릭 클래스이다.
- 타입 안정성이 유지된다.
- 형 변환이 필요없다.
② 동적 크기 조정
- 내부적으로는 배열을 사용한다.
- 하지만 공간이 부족하면 자동으로 더 큰 배열을 만든다.
items // 실제 데이터 배열
size // 실제 저장된 데이터 개수
capacity // 현재 배열 크기
- List가 내부적으로 가지는 데이터는 이와 같다.
③ 용량 증가 방식
List<int> list = new List<int>();
- 데이터를 추가하다가 공간이 부족하면 아래와 같이 재할당(Reallocation)이 일어난다.
1. 더 큰 배열이 생성된다.
2. 기존 데이터를 복사한다.
3. 기존 배열 대신 새 배열을 사용한다.
④ 배열처럼 인덱스 접근 가능
Console.WriteLine(list[0]);
- 배열처럼 빠르게 접근이 가능하다.
(6) 주요 메서드
① Add
list.Add(10);
- 리스트 끝에 데이터를 추가한다.
② Insert
list.Insert(1, 50);
- 특정 위치에 데이터를 삽입한다.
③ Remove
List.Remove(10);
- 특정 데이터를 제거한다.
④ Clear
list.Clear();
- 모든 데이터를 제거한다.
- 단, 할당되어 있는 공간(Capacity)를 회수해가지 않는다.
⑤ Contains
list.Contains(100);
- 특정 데이터 존재 여부를 확인한다.
⑥ IndexOf
list.IndexOf(100);
- 특정 데이터 위치 반환한다. 없으면 -1을 반환한다.
⑦ Sort
list.Sort();
- list에 대한 정렬을 진행한다. (기본적으로 오름차순이다.)
(7) List의 장점
- 배열보다 사용이 편리하다.
- 크기를 자동으로 조정해준다.
- 타입 안정성이 유지된다.
- 박싱 / 언박싱 문제를 줄일 수 있다.
- 배열처럼 인덱스 접근이 가능하다.
(8) 주의점
- 내부적으로 배열을 사용하므로, 중간 삽입 / 삭제를 진행하면 데이터 이동 비용이 발생한다.
- 용량이 부족해 재할당이 발생하면 기존 데이터 복사가 필요하다.
- 따라서 보통 Capacity를 미리 지정하여 사용하기도 한다.
List<string> items = new List<string>(200);
- 예상 개수를 미리 생각해서 내부 배열 크기를 잡아 재할당을 줄일 수 있다.
- List 자체와 내부 배열은 참조 타입이다. 따라서 타입 객체이므로 이는 GC 대상이다. 다만, ArrayList 처럼 값 형식을 object 로 저장할 때 발생하는 박싱 / 언박싱을 줄일 수 있다.
- 따라서, 불필요한 힙 할당과 GC 부담을 줄이는데 도움이 된다.
(9) 정리
- List<T>는 제네릭 기반 동적 배열 클래스이다.
- 배열처럼 인덱스로 접근 가능하면서도 크기를 자동으로 조절할 수 있다.
- 기존 배열의 고정 크기 문제와 ArrayList의 타입 안정성 문제를 개선했다.
- 내부적으로는 배열을 사용하며, 공간이 부족하면 더 큰 배열을 복사하고, 데이터를 복사한다.
'Unity > Unity 초격차캠프' 카테고리의 다른 글
| [20260513] C# ( 제네릭 제약 ) (0) | 2026.05.13 |
|---|---|
| [20260512] C# ( Boxing & UnBoxing ) (0) | 2026.05.12 |
| [20260512] C# ( 제네릭 프로그래밍 ) (0) | 2026.05.12 |
| [20260511] C# ( 객체지향 설계 5대 원칙 SOLID ) (0) | 2026.05.11 |
| [20260508] C# (Upcasting, Downcasting, is / as) (0) | 2026.05.08 |