3. 제네릭(generic)
제네릭이 처음 등장한 건 2005년 C# 2.0과 .NET Framework 2.0 때인데 당시 마이크로소프트는 제네릭을 Type을 매개변수로 전달함으로써 Type이 좀 더 효율적이고 안전하게 재사용될 수 있도록 할 수 있다고 소개한 바 있습니다.
제네릭의 유용성을 알아보기 위해서는 우선 실제 제네릭을 사용할 수 없을 때의 코드가 구현되는 경우를 먼저 살펴볼 필요가 있습니다. 제네릭이 등장하기 이전에는 매개변수에서 값을 다루는데 취약한 면이 있었으며 대안으로 사용했던 System.Object형식을 사용하는 것 자체가 성능 저하의 문제를 유발할 수 있었습니다.
예를 들어 HashTable에 특정 키와 값을 담아두는 아래와 같은 경우를 보면
System.Collections.Hashtable ht = new();
Car c = new() { Brand = "C", speed = 80 };
ht.Add(key: 1, value: "first");
ht.Add(key: 2, value: "second");
ht.Add(key: 3, value: "third");
ht.Add(key: c, value: "자동차");
Console.WriteLine(ht[c]);
//자동차
1부터 3까지는 단순 정수를 key로서 할당하고 있지만 마지막 네 번째에서는 Car Type을 그대로 key로서 지정하고 있습니다.
System.Collections.Hashtable은 각각 개별적인 다수의 키와 값을 object형식으로 저장할 수 있으며 빠르게 key를 통해 값을 가져올 수 있는 기능을 제공하고 있습니다. 따라서 key와 값이 숫자든, 문자열이든 아니면 예제에서 처럼 자체적인 Type이든 상관없이 모든 형식을 담아낼 수 있습니다. 형식 자체가 object로 정의되어 있기 때문에 가능한 일인데 얼핏 생각해 보면 꽤 높은 수준의 유연성을 제공하는 것처럼 보일 수 있지만 미처 생각지 못한 Type이 저장될 수 있으므로 인해 잠재적인 버그를 안고 있을 수 있고 또한 형 변환을 매번 수행해야 하므로 성능에도 좋지 않은 영향을 주게 됩니다.
제네릭은 바로 이러한 문제를 해결하고자 등장한 개념인데 위 예제와 동일하게 사용할 수 있는 것으로 System.Collections.Generic.Dictionary<TKey, TValue>가 있습니다. 역시 키와 값을 쌍으로 모든 형식을 저장할 수 있지만 차이점이라면 compiler에게 저장될 Type을 지정해야 한다는 것입니다. System.Collections.Generic.Dictionary에 있는 <TKey, TValue>가 Type이 지정되어야 한다는 것을 말해주고 있는데 이때 Generic에서 List<T>나 Dictionary<TKey, TValue>에서 명시된 T는 Type을 의미합니다.
이전에 예제에서 System.Collections.Hashtable을 Dictionary<int, string>로 수정하게 되면
Dictionary<int, string> ht = new();
Car c = new() { Brand = "C", speed = 80 };
ht.Add(key: 1, value: "first");
ht.Add(key: 2, value: "second");
ht.Add(key: 3, value: "third");
ht.Add(key: c, value: "자동차");
Console.WriteLine(ht[c]);
네번째 Car를 key로 잡은 부분부터 오류를 발생시키게 되고
당연히 컴파일도 불가능하게 됩니다. 이미 <int, string>을 통해 key와 값에서 어떤 값이 들어와야 한다는 것을 명시했기 때문입니다.
'.NET > C#' 카테고리의 다른 글
[C#] 인터페이스(Interface)와 상속(Inheriting) - 4. 참조타입과 값타입 (0) | 2022.06.24 |
---|---|
[C#] 인터페이스(Interface)와 상속(Inheriting) - 3. 인터페이스(Interface) (0) | 2022.06.24 |
[C#] 인터페이스(Interface)와 상속(Inheriting) - 1. 메서드(Method)와 이벤트(Event) (0) | 2022.06.24 |
[C#] C#과 OOP(Object-Oriented Programming) - 7. 레코드(Record) (0) | 2022.06.24 |
[C#] C#과 OOP(Object-Oriented Programming) - 6. 패턴 매칭(Pattern Matching) (0) | 2022.06.24 |