Generic(제네릭)

김재섭·2022년 12월 12일
0

Generic이란

Generic은 '타입(Type)을 미리 정하지 않고(포괄적인 상태로 해두고), 그것을 사용할 시점에 타입을 정의'하는 것을 말한다.
*generic : 포괄적인, 총칭의
https://fiftiesstudy.tistory.com/221

제네릭은 앞의 글에 나온 박싱, 언박싱의 단점을 극복하기 위해 만들었다고 한다.

우선 제네릭을 사용하지 않는 사례부터 천천히 예시를 들어보자.

타입이 고정적인 클래스의 단점

public class NoGeneric
{
    public int example;
    
    public void PrintExample()
    {
        Debug.Log(classInt);
    }
}

클래스 NoGeneric이 있다.
Int형 변수인 example을 가지고 있고,
그 example을 출력해주는 PrintExample 메서드를 하나 가지고 있는 클래스이다.

다른 클래스인 Test에서 이 기능을 사용하려면, 이렇게 하면 된다.

public class NoGeneric
{
    public int example;
    
    public void PrintExample()
    {
        Debug.Log(example);
    }
}
public class Test : MonoBehaviour
{

     private void Awake()
    {
        NoGeneric noGeneric = new NoGeneric();
        noGeneric.example = 111;
        noGeneric.PrintExample();
    }
}
-------------------------------
Log: 
111

여기까지는 제너릭을 사용하지 않은 보통의 방법이다.

하지만 PrintExample는 int형만 출력이 가능한데, 나중에 갑자기 추가로 float형을 출력하도록 구현해야한다면?

그때마다 이렇게 따로 함수와 변수를 만들어줘야한다.

public class NoGeneric
{
    public int example;
    public float example2;
    
    public void PrintExample()
    {
        Debug.Log(example);
    }
    public void PrintExample2()
    {
        Debug.Log(example2);
    }
    
}
public class Test : MonoBehaviour
{

     private void Awake()
    {
        NoGeneric noGeneric = new NoGeneric();
        noGeneric.example = 111;
        noGeneric.PrintExample();
        
        NoGeneric noGeneric = new NoGeneric();
        noGeneric.example2 = 3.14f;
        noGeneric.PrintExample2();
    }
}
-------------------------------
Log: 
111
3.14

음 정말 번거롭다.
지금이야 변수하나, 출력하는 한줄만 있는 간단한 코드라서 이렇게 떼울 수 있지만, 코드가 길어질수록 그러기는 힘들다.

타입이 다르다는 이유로 같은 기능의 코드를 여러번 쓴다는건 정말 싫을것같다. 수정이라도 하게된다면....😥

하지만 제네릭을 쓴다면?

Generic 사용 예제

public class YesGeneric<T>
{
    public T example;
    public void PrintExample()
    {
        Debug.Log(example);
    }
}

public class Test : MonoBehaviour
{
    private void Awake()
    {
        YesGeneric<int> genericTestA = new YesGeneric<int>();
        genericTestA.example = 1;
        genericTestA.PrintExample();

        YesGeneric<float> genericTestB = new YesGeneric<float>();
        genericTestB.example = 1.5f;
        genericTestB.PrintExample();

        YesGeneric<string> genericTestC = new YesGeneric<string>();
        genericTestC.example = "test";
        genericTestC.PrintExample();

        YesGeneric<NoGeneric> genericTestD = new YesGeneric<NoGeneric>();
        genericTestD.example = new NoGeneric() { classInt = 10 };
        genericTestD.PrintExample();
    }
}
-------------------------------
Log: 
1
1.5
test
NoGeneric

YesGeneric클래스 뒤에 <T>를 써주고, 담고있는 변수들에는 타입 대신 T 를 써준다.
Test클래스에서 YesGeneric클래스를 사용할때, 선언할 때에 클래스이름 뒤에 <타입>을 넣어주면 된다.

선언부분에서 익숙한 느낌이 든다면, 익숙한게 맞다. List나 Dictionary같은 클래스를 사용할때에도 우리는 이렇게 해왔었다.
ex) List intEx = new List();

아무튼,YesGeneric 클래스 부분을 보면 공백 제외하면 3줄밖에 안된다.
단 3줄로 사용할때에 int로,float으로,string으로, 심지어 클래스인 NoGeneric로도 타입을 넣어서 사용할 수 있다.

정리

항상 퇴근하고 쓰느라고 시간이 늦는다.. 원래 더 길게 쓰고싶었는데ㅠ
이번 글에서는 제네릭을 클래스와 필드 , 메서드에 사용했다.
다음글에서는 생성자와 프로퍼티에도 써먹을 수 있다는걸 이어서 정리하고, 내일 생각나는거 추가로 또 해야겠다.

profile
Unity C#

0개의 댓글