[C#] 제네릭(Generics)
제네릭은 int, float, double 같은 데이타 요소 타입을 확정하지 않고 이 데이타 타입 자체를 타입파라미터로 받아들이도록 클래스를 정의한다.
클래스를 사용시 클래스명과 사용타입을 함께 지정해 사용한다. 사용시 <T> 같은 타입 파라미터를 붙여 구현한다.
제네릭의 장점
- 캐스팅으로 인한 낭비가 줄어듬
- 형식의 안정성
- 박싱, 언박싱으로 인한 부하가 없다.
제네릭의 제약조건
제네릭 타입인수 T는 별다른 지정이 없으면 object이므로 object의 메서드만 사용할 수 있다.
제약 조건 |
설 명 |
where T : struct |
T는 값 타입이어야 하며 참조 타입을 쓸 수 없다. 단 Nullable 타입은 값 타입이지만 예외적으로 이 제약 조건에서 허용되지 않는다. |
where T : class |
T는 참조 타입이어야 하며 값 타입을 쓸 수 없다. |
where T : new() |
디폴트 생성자가 있어야한다. new T() 형태로 객체를 생성할 수 있어야한다. 타 조건과 함께 쓸 경 우 마지막에 지정해야한다. |
where T : base |
T는 base로부터 파생된 클래스여야 한다. |
where T : Ibase |
T는 Ibase 인터페이스를 반드시 구현해야 한다. 클래스와는 달리 여러 개의 인터페이스를 지정할 수 있다. |
where T : P | 두 타입 인수 사이의 관계가 파생 관계여야 한다. T가 P 파생 클래스여야 한다. |
using System; using System.Collections.Generic; namespace GenericCollections { class Program { public static void TestDictionary() //Dictionary { Dictionary
genDic = new Dictionary (); genDic.Add("txt", "notepad.exe"); genDic.Add("bmp", "paint.exe"); genDic.Add("mp3", "foobar.exe"); Console.WriteLine("[Dictionary]"); foreach( KeyValuePair kvp in genDic ) { Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value); } Console.WriteLine(); } public static void TestLinkedList() //LinkedList { LinkedList genLL = new LinkedList (); genLL.AddLast("4등"); genLL.AddFirst("1등"); genLL.AddAfter(genLL.Find("1등"), "2등"); genLL.AddBefore(genLL.Find("4등"), "3등"); Console.WriteLine("[LinkedList]"); foreach( string str in genLL ) Console.WriteLine("Value = {0}", str); Console.WriteLine(); } public static void TestList() //List { List genList = new List (); genList.Add("한국"); genList.Add("중국"); genList.Add("중국2"); genList.Remove("중국2"); Console.WriteLine("[List]"); foreach (string str in genList) Console.WriteLine("Value = {0}", str); Console.WriteLine(); } public static void TestQueue() //Queue { Queue genQueue = new Queue (); genQueue.Enqueue(1); genQueue.Enqueue(2); genQueue.Enqueue(3); Console.WriteLine("[Queue]"); for( int i=0; i<3; i++ ) Console.WriteLine("Value = {0}", genQueue.Dequeue()); Console.WriteLine(); } public static void TestStack() //Stack { Stack genStack = new Stack (); genStack.Push(1); genStack.Push(2); genStack.Push(3); Console.WriteLine("[Stack]"); for (int i = 0; i < 3; i++) Console.WriteLine("Value = {0}", genStack.Pop()); Console.WriteLine(); } public static void Main() { TestDictionary(); TestLinkedList(); TestList(); TestQueue(); TestStack(); } }