728x90
반응형
System.Collections 네임스페이스에 있는 클래스들은 몹시 유용하지만, 모든 타입의 데이터를 수용하기 위해 Object형으로 데이터를 저장하기에 연산을 위해서 형변환을 하거나 타입 체크를 하기 번거롭고, 속도 자체도 느릴수밖에 없다. 이를 개선해서 설정한 타입만을 데이터로 받는 제네릭 컬렉션 클래스가 있다. 이에 대해 간단히 정리하겠다.
관련 네임스페이스 : using {NAMESPACE}로 사용 | 자주 쓰이는 클래스 |
System | Array |
System.Collections | Stack, Queue, ArrayList, Hashtable |
System.Collections.Generic | Stack<T>, Queue<T>, List<T>, Dictionary<T> |
Stack<T> 제네릭 클래스
- 필요한 네임스페이스를 선언하고, 제네릭 클래스의 인스턴스를 생성한 후 메소드를 사용한다.
- 지난 포스팅에서 소개한 컬렉션 Stack 클래스의 사용법에서 <타입>만 추가한 형태이다.
using System.Collections.Generic;
class GenericPractice
{
static void Main()
{
Stack<string> stack = new Stack<string>();
stack.Push("Hello Generic");
Console.WriteLine(stack.Pop());
}
}
//출력 : Hello Generic
제네릭 클래스의 장점
제네릭 클래스는 컬렉션 클래스와 비교해 다음과 같은 장점을 지닌다.
- 전달 시 추가적인 형변환 필요없음
using System.Collections.Generic;
class GenericPractice
{
static void Main()
{
Stack<int> stack = new Stack<int>();
stack.Push(1111);
//컬렉션 Stack 클래스의 경우, int integer = (int)stack.Pop();
//제네릭 클래스는 형변환 없이 바로 전달
int integer = stack.Pop();
Console.WriteLine(integer);
}
}
//출력 : 1111
- 박싱, 언박싱에 대한 비용 절감
- 컬렉션 Stack 클래스의 경우 모든 데이터 타입을 수용하는데, 이는 모든 데이터 타입을 "Object"형으로 변환해 저장하기 때문이다. 더 정확히 말하면, 실행시간 중 메모리 내의 힙 영역에 Object 타입의 참조형 변수를 생성하고, 입력 데이터 값을 저장한 후 생성한 변수의 주소를 반환한다. 입력 데이터를 Object 타입의 참조형 변수로 저장하는 것을 "박싱", Object 타입의 참조형 변수를 원하는 데이터 형식으로 바꿔 사용하는 것을 "언박싱"이라고 한다.
- 박싱과 언박싱은 설명에도 알 수 있듯 추가적인 작업을 요구하기 때문에 속도가 느리며 자원을 소모한다. 제네릭 클래스는 데이터 형식이 지정되어 있기 때문에 박싱과 언박싱이 필요없다.
using System.Collections;
class GenericPractice
{
static void Main()
{
Stack stack = new Stack();
//int형을 object형으로 박싱
stack.Push(2222);
//object형을 int형으로 언박싱
int integer = (int)stack.Pop();
Console.WriteLine(integer);
}
}
//출력 : 2222
- 의도치 않은 데이터 타입 입력 방지
using System.Collections.Generic;
class GenericPractice
{
static void Main()
{
Stack<string> stack = new Stack<string>();
stack.Push("1111");
//에러 발생 : Error CS1503 : 1 인수: 'int'에서 'string'(으)로 변환할 수 없습니다.
stack.Push(1111);
}
}
Queue<T> 제네릭 클래스
- 필요한 네임스페이스를 선언하고, 제네릭 클래스의 인스턴스를 생성한 후 메소드를 사용한다.
- 지난 포스팅에서 소개한 컬렉션 Queue 클래스의 사용법에서 <타입>만 추가한 형태이다.
using System.Collections.Generic;
class GenericPractice
{
static void Main()
{
Queue<string> queue = new Queue<string>();
queue.Enqueue("queue!!");
Console.WriteLine(queue.Dequeue());
}
}
//출력 : queue!!
List<T> 제네릭 클래스
- 필요한 네임스페이스를 선언하고, 제네릭 클래스의 인스턴스를 생성한 후 메소드를 사용한다.
- 지난 포스팅에서 소개한 컬렉션 ArrayList 클래스의 사용법에서 <타입>만 추가한 형태이다.
- List 제네릭 클래스는 특히 많이 사용된다.
using System.Collections.Generic;
class GenericPractice
{
static void Main()
{
List<string> fruits = new List<string>();
fruits.Add("apple");
fruits.Add("peach");
fruits.Add("cherry");
for (int i = 0; i < fruits.Count; i++)
{
Console.WriteLine($"{fruits[i]}");
}
}
}
//출력 : apple peach cherry
Dictionary<T, T> 제네릭 클래스
- 필요한 네임스페이스를 선언하고, 제네릭 클래스의 인스턴스를 생성한 후 메소드를 사용한다.
- 지난 포스팅에서 소개한 컬렉션 Hashtable 클래스와 유사한 구조에 <타입>을 추가했다.
- 없는 키를 요청하면 에러가 발생하는데, 이를 확인 및 제어하기 위한 메서드도 존재한다.
using System.Collections.Generic;
class GenericPractice
{
static void Main()
{
Dictionary<string, string> dic = new Dictionary<string, string>();
//딕셔너리 데이터 추가
dic.Add("C#", "fun");
dic.Add("Python", "easy");
dic.Add("C", "Oh..");
//딕셔너리 데이터 삭제 : 키 기준
dic.Remove("C");
//인덱서를 이용한 데이터 추가
dic["C"] = "awesome"
//딕셔너리 출력
foreach (var lang in dic)
{
Console.WriteLine("{0} is {1}", lang.Key, lang.Value);
}
}
}
//출력 : C# is fun Python is easy C is awesome
이상으로 자주 쓰이는 제네릭 클래스를 간단히 다뤄보았다. 더 많은 제네릭 클래스와 제네릭 메서드가 있지만, 위의 내용이 이해가 됬다면 공식 문서에서 추가로 읽고 Rider나 비주얼 스튜디오의 도움을 받아 사용하면 될 듯하다.
볼 사람을 위한 링크
https://learn.microsoft.com/ko-kr/dotnet/api/system.collections.generic?view=net-8.0
https://learn.microsoft.com/ko-kr/dotnet/csharp/programming-guide/generics/generic-classes
728x90
반응형
'C#' 카테고리의 다른 글
[C#] 대리자(Delegate; 델리게이트)와 무명 메서드(+람다식 기초) (1) | 2024.04.26 |
---|---|
[C#] 참조 매개 변수, ref와 out의 차이점 (0) | 2024.04.25 |
[C#] 값 형식과 참조 형식, 박싱과 언박싱(힙 메모리), is 연산자와 as 연산자 (0) | 2024.04.25 |
[C#] 다차원 배열과 가변 배열(C/C++ 문법과 차이점) (0) | 2024.04.25 |
[C#] 널(NULL) 관련 형식[Nullable<T>] 및 연산자[??, ?.] (1) | 2024.04.24 |
[C#] 컬렉션(Collection) 클래스 (0) | 2024.04.24 |
[C#] Rider 내 실습용 콘솔 솔루션 생성 & 유용한 문자열 형식, 표기법 (1) | 2024.04.23 |
[C#] 초기 개발 환경 설정(Rider) 및 유니티 연동 + SDK 8.0 설치 (0) | 2024.04.23 |