2024. 9. 29. 20:39ㆍc#
C# 제네릭 클래스 및 메서드 정의
C#에서 제네릭(Generics)은 다양한 타입을 하나의 클래스 또는 메서드에서 처리할 수 있게 해주는 강력한 기능입니다.
제네릭은 코드의 재사용성을 높이고, 타입 안정성을 보장하며, 더 적은 코드로 다양한 타입의 작업을 수행할 수 있게 해줍니다. 이번 포스팅에서는 제네릭 클래스와 제네릭 메서드의 개념과 사용법을 설명합니다.
1. 제네릭이란?
제네릭은 데이터 타입을 일반화하여 클래스, 메서드, 구조체, 인터페이스가 여러 데이터 타입에서 재사용될 수 있도록 해줍니다. 제네릭을 사용하면 타입에 대한 의존성을 줄이면서도 강력한 형식 검사를 통해 타입 안정성을 유지할 수 있습니다.
제네릭의 장점
- 재사용성: 다양한 데이터 타입에 대해 동일한 코드를 작성할 수 있습니다.
- 타입 안전성: 컴파일 타임에 타입 검사가 이루어져 런타임 오류를 줄일 수 있습니다.
- 성능 향상: 박싱(Boxing)과 언박싱(Unboxing) 없이 성능을 최적화할 수 있습니다.
2. 제네릭 클래스 정의
제네릭 클래스는 하나의 클래스에서 여러 데이터 타입을 처리할 수 있도록 설계된 클래스입니다. 제네릭 클래스는 클래스 이름 뒤에 형식 매개변수를 지정하여 정의됩니다.
제네릭 클래스 예시
public class GenericClass<T>
{
private T data;
public GenericClass(T value)
{
data = value;
}
public T GetData()
{
return data;
}
public void SetData(T value)
{
data = value;
}
}
위 예시에서는 T라는 형식 매개변수를 사용하여 제네릭 클래스를 정의하였습니다.
이 클래스는 T 타입의 데이터를 저장하고 반환하는 메서드를 제공합니다.
제네릭 클래스 사용 예시
GenericClass<int> intInstance = new GenericClass<int>(10);
Console.WriteLine(intInstance.GetData()); // 출력: 10
GenericClass<string> stringInstance = new GenericClass<string>("Hello");
Console.WriteLine(stringInstance.GetData()); // 출력: Hello
GenericClass<T>는 int와 string 같은 다양한 타입에서 사용할 수 있으며, 각 인스턴스는 고유한 데이터 타입을 처리할 수 있습니다.
3. 제네릭 메서드 정의
제네릭 메서드는 특정 메서드가 다양한 데이터 타입에서 동작할 수 있도록 만들어진 메서드입니다.
제네릭 메서드는 메서드 이름 앞에 형식 매개변수를 사용하여 정의됩니다.
제네릭 메서드 예시
public class Utility
{
public static void Print<T>(T item)
{
Console.WriteLine(item);
}
}
Print<T> 메서드는 제네릭 메서드로, 매개변수로 전달된 데이터의 타입에 상관없이 그 값을 출력할 수 있습니다.
제네릭 메서드 사용 예시
Utility.Print<int>(100); // 출력: 100
Utility.Print<string>("Hello"); // 출력: Hello
Utility.Print<double>(3.14); // 출력: 3.14
각 호출에서 타입을 명시적으로 지정할 수 있지만, 컴파일러가 타입을 추론할 수 있는 경우 명시하지 않아도 됩니다.
Utility.Print(100); // 타입 추론으로 인해 int로 처리
Utility.Print("Hello"); // 타입 추론으로 인해 string으로 처리
4. 제네릭의 제약조건 (Constraints)
때때로 제네릭 타입에 특정 제약을 걸어야 할 필요가 있습니다.
예를 들어, 제네릭 타입이 특정 인터페이스를 구현하거나 기본 생성자가 필요할 때 제약조건을 사용할 수 있습니다.
제약조건의 종류
- where T : class – T는 참조형이어야 합니다.
- where T : struct – T는 값 형식이어야 합니다.
- where T : new() – T는 기본 생성자가 있어야 합니다.
- where T : SomeBaseClass – T는 특정 클래스나 그 하위 클래스여야 합니다.
- where T : ISomeInterface – T는 특정 인터페이스를 구현해야 합니다.
제네릭 제약조건 예시
public class Repository<T> where T : class, new()
{
public T CreateInstance()
{
return new T();
}
}
위 예시에서는 T가 클래스여야 하고, 기본 생성자가 있어야 한다는 제약을 걸었습니다.
5. 제네릭을 사용하는 실제 예
C#에서 제네릭은 컬렉션을 정의하는 데 자주 사용됩니다.
예를 들어, List<T>, Dictionary<TKey, TValue>, Queue<T>, Stack<T> 등 많은 컬렉션 클래스는 제네릭으로 정의되어 있어 다양한 데이터 타입을 처리할 수 있습니다.
List<T> 예시
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
numbers.Add(6);
foreach (int number in numbers)
{
Console.WriteLine(number);
}
이러한 제네릭 컬렉션은 타입 안전성을 보장하며, 박싱/언박싱 없이 성능을 최적화할 수 있습니다.
제네릭 클래스와 제네릭 메서드는 C#에서 코드의 재사용성을 극대화하는 중요한 도구입니다.
제네릭을 사용하면 다양한 타입에 대해 동일한 코드를 작성할 수 있으며, 타입 안정성을 유지하면서 더 간결하고 유연한 코드를 구현할 수 있습니다. 또한, 제네릭 제약조건을 사용하여 더 강력한 타입 검사를 구현할 수 있습니다.
제네릭을 통해 코드의 가독성을 높이고 유지보수성을 향상시키는 것은 물론, 프로그램의 성능을 최적화할 수 있습니다.
'c#' 카테고리의 다른 글
c# 제네릭(Generic)과 컬렉션(Collection)의 관계의 유연성 확보 (0) | 2024.09.29 |
---|---|
c# 제네릭(Generic)을 사용한 자료형의 유연성 확보 (0) | 2024.09.29 |
c# IEnumerable 확장 메서드 (0) | 2024.09.29 |
c# IEnumerable과 IEnumerator (0) | 2024.09.29 |
c# 컬렉션(Collection)의 성능 및 메모리 관리 (0) | 2024.09.29 |