제너릭 메소드
제너릭 메소드는 이처럼 형식 매개 변수를 사용하여 선언된 메소드이다.
static void Swap<T>(T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
위처럼 선언을 하지않고, 메소드 이름 옆에 <T>를 제거하면 오류가 발생하는 것을 볼 수 있다. 사실 <T>가 없어도 바로 쓸 수 있을 것이라 생각하였는데, 그렇지 않았다.
형식 인수 int를 사용하여 제너릭 메소드를 사용하는 법
static void Swap<T>(ref T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
static void Main(string[] args)
{
int a = 1;
int b = 2;
Swap<int>(ref a, ref b);
Console.WriteLine($"a: {a}, b: {b}");
}
물론 아래처럼 형식 인수를 생략하고 자동으로 타입을 유추하도록 할 수도 있다.
static void Main(string[] args)
{
int a = 1;
int b = 2;
Swap(ref a, ref b);
Console.WriteLine($"a: {a}, b: {b}");
}
a, b 변수의 타입이 다르면?
a, b의 변수의 타입을 다르게 선언하면 컴파일러에서 제너릭 메소드의 형식 매개변수에 대한 유추에 실패한다. 위 상황에서 타입을 지정하게 되면, 다음 에러 메시지를 확인할 수 있다.
클래스 내부에서 제너릭 메소드
제너릭 클래스 내에서 제너릭이 아닌 메소드는 다음과 같은 클래스 수준의 형식 매개 변수에 액세스 할 수 있다.
class SampleClass<T>
{
void Swap(ref T lhs, ref T rhs) { }
}
제너릭 클래스가 아니었다면 형식 매개변수 T에 접근하기 위해 `static void Swap<T>(T lhs, ref T rhs)`와 같이 사용해야 했을 것이다.
클래스와 동일한 형식 매개 변수를 사용하는 제너릭 메소드를 정의하면 컴파일러에서 CS0693 경고가 발생한다. 메소드 범위 내부 `T`에 제공된 인수가 외부 `T`에 제공된 인수를 숨긴다.
그래서 클래스를 인스턴스화 할 때 제공한 형식 인수가 아닌 다른 형식 인수를 사용하여 제너릭 클래스 메소드를 호출하려면, 아래와 같이 메소드 형식 매개 변수에 다른 식별자를 제공하면 된다.
제약 조건의 사용
메소드 형식 매개변수에 대해 더 구체적인 작업을 수행하려면 제약 조건을 지정하면 된다.
void SwapIfGreater<T>(ref T lhs, ref T rhs) where T : System.IComparable<T>
{
T temp;
if (lhs.CompareTo(rhs) > 0)
{
temp = lhs;
lhs = rhs;
rhs = temp;
}
}
`SwapIfGreater<T>`함수는 `IComparable<T>`를 구현하는 타입의 매개변수만 받을 수 있다고 위처럼 지정할 수 있다.
참고자료
https://learn.microsoft.com/ko-kr/dotnet/csharp/programming-guide/generics/generic-methods
'C#' 카테고리의 다른 글
[C#] Public 필드와 프로퍼티 (0) | 2024.12.20 |
---|---|
[C#] Delegate, EventHandler 그리고 구조에 대한 고민 (0) | 2024.12.06 |
[C#] CS0273에러 accessor must be more restrictive than the property or indexer (1) | 2024.09.25 |
[C#] 데이터 타입 (0) | 2023.01.05 |
[C#] 변수 (0) | 2023.01.04 |