내일배움캠프 TIL

내일배움캠프 50일차 TIL "제네릭"

Jooglorystar 2024. 11. 27. 21:54

 

 

프로젝트를 진행하던 중, 싱글톤화 하는 것이 필요한 클래스에 상속할 수 있는 제네릭을 이용한 클래스가 있었다.

다음과 같은 코드이다. 

 

public class ConvertToSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T _instance;

    public static T Instance
    {
        get
        {
            return _instance;
        }
    }
    
    protected virtual void Awake()
    {
        if (_instance == null)
        {
            _instance = this as T;
        }
        else
        {
            Destroy(gameObject);
        }
    }
}

 

이 코드에서 'T'가 제네릭이 되며, 선언할 때, 해당 클래스를 넣을 경우 T자리에 해당 클래스를 넣은 것이 된다.

 

예를들어 TimeManager라는 클래스에 해당 클래스를 상속받는다고 했을 때, 다음과 같이 쓸 수 있을 것이다.

 

public class TimeManager : ConvertToSingleton<TimeManager>
{
	// 클래스 내용
}

 

그럼 적용되는 것은 다음과 같다.

 

 

    private static TimeManager _instance;

    public static TimeManager Instance
    {
        get
        {
            return _instance;
        }
    }
    
    protected virtual void Awake()
    {
        if (_instance == null)
        {
            _instance = this as TimeManager;
        }
        else
        {
            Destroy(gameObject);
        }
    }

 

 

만약 ConvertToSingleton를 구현하지 않았다면 싱글톤화가 필요한 모든 클래스에 해당 코드를 작성해야할 수도 있었지만,

해당 코드를 구현함으로서, 단순히 상속하기만 하면 간단하게 해당 클래스에 싱글톤을 구현할 수 있게 되었다.

 

 

*where 키워드

 

public class ConvertToSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
}

 

여기서 사용된 where 키워드는 제약조건을 거는데 사용되는 메서드이다. 

위 코드의 경우, 여기에서 사용되는 제네릭이 무조건 MonoBehaviour를 상속받아야한다는 것을 의미한다.

위 코드에서 실제로는 ConvertToSingleton<T>가 MonoBehaviour를 상속받기에 해당 조건에 맞지 않는 경우는 없을 것으로 보인다.

 

 

*as 키워드

 

    private static T _instance;

    public static T Instance
    {
        get
        {
            return _instance;
        }
    }
    
    protected virtual void Awake()
    {
        if (_instance == null)
        {
            _instance = this as T;
        }
        else
        {
            Destroy(gameObject);
        }
    }

 

 

위 코드에서 사용된 as키워드는 this를 제네릭의 형식으로 전환을 시도하고, 성공하면 _instance에 참조에 성공하고, 실패할 경우, null이 된다. as키워드를 사용함으로써, _instance에 제네릭 값을 안정적으로 참조할 수 있게 된다.