[C#] 제너릭 메소드

Artiper
|2024. 10. 6. 22:47

 

제너릭 메소드

제너릭 메소드는 이처럼 형식 매개 변수를 사용하여 선언된 메소드이다.

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 변수의 타입이 다르면?

CS0411 에러메시지

 

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