[유니티 / C#] 제네릭 (Generic)

⭐ 제네릭

타입 매개변수를 사용해 클래스, 메서드, 인터페이스 등을 정의하여 형식 매개변수에 따라 컴파일 시점에 강력한 형식 검사와 코드 재사용을 제공하는 기능입니다.

 

 

● 싱글턴, 오브젝트 풀링 등 여러 타입에서 사용해야할 베이스 클래스를 만들 때 사용하면 좋습니다.

    ○ 컴파일 시점에 타입을 결정해서 타입 안정성이 좋습니다.

    ○ 하나의 코드로 여러 타입이 사용 가능하니 코드 재사용성이 높습니다.

    ○ 박싱, 언박싱에 비해 성능면에서도 뛰어납니다.

    ○ where 키워드를 사용해 제약을 걸 수도 있습니다.

 


 

제네릭 클래스

class Program
{
    static void Main(string[] args)
    {
        GenericTest<int> intTest = new GenericTest<int> { Value = 10 };
        GenericTest<string> stringTest = new GenericTest<string> { Value = "제네릭" };

        intTest.PrintValue();
        stringTest.PrintValue();
    }
}

public class GenericTest<T>
{
    public T Value { get; set; }

    public void PrintValue()
    {
        Console.WriteLine(Value);
    }
}

출력 결과:

10
제네릭

 

● GenericTest<T>: 클래스에 있는 T가 타입 매개변수입니다. 다른 매개변수명을 사용해도 되지만 Type의 약자인 T가 관행처럼 사용됩니다.

 

● 메인 함수에서 GenericTest로 다양한 타입을 이용해 객체를 생성할 수 있습니다.

 

 

 

class Program
{
    static void Main(string[] args)
    {
        GenericTest<int> intTest = new GenericTest<int> { Value = 10 };   //int는 class가 아니여서 에러
        GenericTest<string> stringTest = new GenericTest<string> { Value = "제네릭" }; //생성
    }
}

public class GenericTest<T> where T : class
{
    public T Value { get; set; }
}

 

● where 키워드를 통해 제약 조건을 정할 수 있습니다.

    ○ where T : class - T는 클래스를 상속받는 타입이어야 한다는 조건

    ○ 조건에 충족하지 못하면 타입 에러가 뜹니다.

 

● 메인문에서 intTest는 에러, stringTest는 정상적으로 생성됩니다.

    ○ int는 구조체 타입이기 때문에 조건에 맞지 않습니다.

    ○ string은 클래스이기 때문에 조건에 맞습니다.

 

 

 

 

class Program
{
    static void Main(string[] args)
    {
        GenericTest<Player, int> genericTest = new GenericTest<Player, int>(new Player(), 5);
    }
}

public class GenericTest<T, U>
    where T : class, new()
    where U : struct
{
    public T value;
    public U number;

    public GenericTest(T t, U u)
    {
        value = t;
        number = u;
    }
}

public class Player { }

 

● 타입 매개변수를 두 개 선언할 수도 있습니다. 생성자 또한 가능합니다.

    ○ 제약 조건에서 new()는 매개변수가 없는 기본 생성자를 가지는 형식에 대한 제약 조건입니다.

 

 

 

 

public class GenericTest<T, U>
    where T : class, new()
    where U : struct
{
    public T value;
    public U number;

    public GenericTest(T t, U u)
    {
        value = t;
        number = u;
    }

    public void GetValue(out T t, out U u)
    {
        t = value;
        u = number;
    }
}

 

● 제네릭 메서드 또한 만들 수 있습니다.