개발공부/C#

[Effective C#] 아이템 25 : 타입 매개변수로 인스턴스 필드를 만들 필요가 없다면 제네릭 메서드를 정의하라

개발자 찐빵이 2021. 12. 1. 00:12
728x90

타입 매개변수로 인스턴스 필드를 만들어야 하는 경우에는 제네릭 클래스를 작성하고, 그렇지 않은 경우에는 제네릭 메서드를 작성하는 게 좋다.

제네릭으로 Min, Max 메서드를 작성해보자.

제네릭 클래스로 구현하기

public static class Utils<T>
{
    public static T Max(T left, T right) =>
            Comparer<T>.Default.Compare(left, right) < 0 ? right : left;

    public static T Min(T left, T right) =>
            Comparer<T>.Default.Compare(left, right) < 0 ? left : right;
}

// 숫자 비교 방법
double d1 = 4;
double d2 = 5;
double max = Utils<double>.Max(d1, d2);

// 문자열 비교 방법
string foo = "foo";
string bar = "bar";
string sMax = Utils<string>.Max(foo, bar);

위 코드의 문제점

  • 제네릭 클래스로 만들었기 때문에 메서드 호출 시마다 매번 타입 매개변수를 명시적으로 지정해야 한다.
  • Math.Max, Math.Min 메서드를 사용할 수 있지만 항상 런타임에 타입 매개변수가 구현한 Comparer를 구현하는지 확인하고 호출해야 한다.

제네릭 메서드로 구현하면 기능을 용이하게 구현할 수 있다.

제네릭 메서드로 구현하기

public static class Utils
{
    public static T Max(T left, T right) =>
            Comparer<T>.Default.Compare(left, right) < 0 ? right : left;

    public static double Max(double left, double right) => //제네릭 메서드
        Math.Max(left, right);

    public static T Min(T left, T right) =>
            Comparer<T>.Default.Compare(left, right) < 0 ? left : right;

    public static double Min(double left, double right) => //제네릭 메서드
        Math.Min(left, right);
}

// 숫자 비교 방법
double d1 = 4;
double d2 = 5;
double max = Utils.Max(d1, d2);

// 문자열 비교 방법
string foo = "foo";
string bar = "bar";
string sMax = Utils.Max(foo, bar);

Min, Max에 대해 오버로딩 메서드를 작성했다.

매개변수 타입이 정확히 일치하는 메서드가 구현되어 있으면 그 메서드가 호출된다.
구체적으로 지정한 메서드는 제네릭 버전보다 효율적으로 동작한다는 장점이 있다.

매개변수 타입이 일치하는 메서드가 없으면 제네릭 메서드가 호출된다.

제네릭 클래스를 작성하는 경우

  • 클래스 내 타입 매개변수로 주어진 타입으로 내부 상태를 유지해야 하는 경우.
  • 제네릭 인터페이스를 구현하는 클래스를 만들어야 하는 경우

위 경우를 제외하고 제네릭 메서드를 포함하는 일반 클래스를 만들어 사용하는 것이 좋다.

반응형