지난 포스팅의 제네릭 메서드에 이어 이번 포스팅에서는 제네릭 클래스에 대해서 다루어 보겠습니다.
제네릭 클래스란?
제네릭 클래스는 멤버의 형을 일반화된 타입인 <T>로 표시한 클래스입니다. 이렇게 하면 클래스 내에서 사용되는 모든 데이터 타입을 T 하나로 처리할 수 있습니다.
제네릭 클래스 선언
제네릭 클래스를 선언하는 방법은 클래스 이름 뒤에 <T>을 붙이면 됩니다. 이렇게 하면 객체가 생성될 때 <> 안에 쓰는 형이 T를 대체하게 됩니다.
public class MyGenericClass<T>
{
public T x;
public T method(T p) { ... }
}
여기서 T는 일반화된 타입 매개변수입니다. float, int, double, string 등 어떤 타입이라도 될 수 있습니다. 클래스를 위와 같이 선언하면 다음과 같이 사용될 수 있습니다.
MyGenericClass<int> x = new MyGenericClass<int>();
MyGenericClass<string> str = new MyGenericClass<string>();
제네릭 클래스의 사용 예제
좀 더 자세한 사용 예제를 보겠습니다. 다음은 리스트 클래스를 제네릭으로 선언하여 사용하는 예제입니다.
using System;
class Program
{
class List<T>
{
private T[] elements;
private int count;
public List()
{
elements = new T[10];
count = 0;
}
public void Add(T element)
{
elements[count] = element;
count++;
}
public T Get(int index)
{
return elements[index];
}
}
static void Main(string[] args)
{
List<int> intList = new List<int>();
intList.Add(1);
intList.Add(2);
Console.WriteLine(intList.Get(0)); // 출력: 1
List<string> stringList = new List<string>();
stringList.Add("Hello");
stringList.Add("World");
Console.WriteLine(stringList.Get(1)); // 출력: World
}
}
[결과]
1
World
위 코드는 제네릭으로 선언된 List 클래스를 이용하여 List<int> 타입의 intList를 생성합니다. List<int>는 T를 int로 지정하여 정수 리스트를 다루고, stringList는 List<string> 타입의 인스턴스를 생성하여, T를 string으로 지정하여 문자열 리스트를 다룹니다.
제한된 제네릭 클래스
제한된 제네릭 클래스는 제네릭 클래스의 타입 매개변수에 대한 제한을 둘 수 있는 기능입니다. 제한된 제네릭 클래스를 사용하면, 제네릭 클래스가 특정 타입에 대해서만 동작하도록 제한할 수 있습니다.
제한된 제네릭 클래스를 사용하는 방법은 where 키워드를 사용하여 타입 매개변수에 대한 제약 조건을 설정하는 것입니다. where 키워드를 사용하면, 타입 매개변수가 특정 조건을 만족하는 경우에만 클래스를 사용할 수 있도록 제한할 수 있습니다.
예를 들어, 숫자 타입에 대해서만 덧셈 연산을 수행하는 제네릭 클래스의 경우, 숫자 타입에 대해서만 덧셈을 지원하도록 제한할 필요가 있습니다.
using System;
class Program
{
class NumericAdder<T> where T : struct
{
public T Add(T a, T b)
{
if (typeof(T) == typeof(int))
{
return (T)(object)((int)(object)a + (int)(object)b);
}
else if (typeof(T) == typeof(double))
{
return (T)(object)((double)(object)a + (double)(object)b);
}
else if (typeof(T) == typeof(float))
{
return (T)(object)((float)(object)a + (float)(object)b);
}
else
{
throw new ArgumentException("Unsupported type");
}
}
}
static void Main(string[] args)
{
NumericAdder<int> intAdder = new NumericAdder<int>();
int result1 = intAdder.Add(1, 2); // 결과: 3
NumericAdder<double> doubleAdder = new NumericAdder<double>();
double result2 = doubleAdder.Add(1.5, 2.5); // 결과: 4.0
NumericAdder<string> stringAdder = new NumericAdder<string>(); // 컴파일 에러 발생!
}
}
위 코드에서 NumericAdder<T> 클래스는 T 타입 매개변수를 가지며, Add 메서드를 제공합니다. 그러나 where T : struct 제약 조건으로 인해 값 타입에 대해서만 동작하도록 제한됩니다.
intAdder은 NumericAdder<int> 타입의 인스턴스를 생성하고, doubleAdder은 NumericAdder<double> 타입의 인스턴스를 생성하여 int와 double 타입에 대한 덧셈을 수행할 수 있습니다.
그러나, stringAdder의 경우, NumericAdder<string> 타입의 인스턴스를 생성하려고 하므로 컴파일 에러가 발생합니다.(string은 참조타입)
'Program Language > C#' 카테고리의 다른 글
Part3. C# 실력다지기(4. LinkedList 이해하기) (5) | 2023.07.15 |
---|---|
Part3. C# 실력 다지기(3. dynamic형 사용하기) (15) | 2023.04.07 |
Part3. C# 실력 다지기(1. 제네릭 메소드 이해하기) (20) | 2023.03.15 |
Part2. C# 기초 다지기(14. params 키워드) (22) | 2023.03.11 |
Part2. C# 기초 다지기(13. 속성) (16) | 2023.03.05 |
댓글