제네릭 특강

Amberjack·2024년 2월 7일
0

C# 문법

목록 보기
43/44

반복되는 숫자는 변수로 사용하면 좋다.

반복되는 로직은 함수로 사용하면 좋다.

반복되는 클래스는 상속을 활용하면 좋다.

반복되어 재사용할 때 필요한 값은 다를 수도 있다.
ex) 함수는 delegate를 활용하여 각각 다른 함수를 실행할 수 있다.

클래스의 경우 Generic 을 통해 여러 타입을 받아줄 수 있다.

ex) GetComponent<>를 할 때, <>는 Generic이다. 이 Generic에 내가 넣고 싶은 컴포넌트 클래스를 넣으면 GetComponent를 사용할 수 있다.
ex) GetComponent<PlayerController>, GetComponent<Animator> 와 같이...

싱글톤

public class GameManager : MonoBehavior
{
	public static GameManager Instance;
    
    void Awake(){
    	Instance = this;
    }
}
public class UIManager : MonoBehavior
{
	public static UIManager Instance;
    
    void Awake(){
    	Instance = this;
    }
}

위와 같이 Manager 가 여러 개가 있어서 싱글톤을 계속 시켜줘야 할 경우, 싱글톤시키는 부분을 상속시켜줄 수 있을 것이다.

// SingletoneBase<T> : 제네릭 클래스, <>를 통해 클래스를 넘겨줄 수 있다.
public class SingletoneBase<T> : MonoBehavior
{
	// public static SingletoneBase Instance; : 이 경우, SingletoneBase을 상속받는 다른 클래스에서는 Instance에 접근할 방법이 마땅치 않다.
    
    public static T Instance;	
    
    void Awake()
    {
    	Instance = this;
    }
}
public class GameManager : SingletoneBase<GameManager>
{
	public Action OnGameStart;
    public Action OnGameEnd;
}
public class UIManager : SingletoneBase<UIManager>
{
	void Start()
    {
    	GameManager.Instance.OnGameStart += OpenStartUI;
        GameManager.Instance.OnGameEnd += OpenCloseUI;
    }
}

동적 생성

만약 GameManager와 UIManager의 Awake 간 실행되어야할 순서가 필요하다고 할 때, GameManager가 먼저 생성이 된 후, Awake가 실행되면 UIManager가 생성되어 Awake되면 된다.

이를 구현하기 위해 프로퍼티를 사용하여 동적 생성을 해보자.

public class SingletoneBase<T> : MonoBehaviour where T : MonoBehaviour
{   
	// 프로퍼티
	private static T _instance;
	
    public static T Instance
    {
    	get
    	{
        	if(_instance == null)
            {
            	string typeName = typeof(T).FullName;
            	GameObject go = new GameObject(typeName);
                _instance = go.AddComponent<T>();
                
                // DontDestroyOnLoad(go);
            }
            return _instance;
        }
    }
}
public class GameScene : MonoBehaviour
{
	void Start()
    {
    	
    }
}

해당 코드는 유니티의 하이라키에서 GameObject를 만드는 것과 같은 원리이다.

where T : MonoBehaviour :
제너릭 T 값에 MonoBehaviour를 상속 받는 것들만 들어오도록 제한 조건을 거는 것이다.
ex) int, float와 같은 값은 T로 들어오지 못하도록 막아주는 것이다.

제너릭은 Object를 상속받은 Type은 모두 가져올 수 있다.
하지만 제너릭은 값을 가지고 올 때마다 Type 을 확인하고 사용해야 한다. → 안그러면 TypeMiss 에러가 발생한다. → 안정성이 떨어진다.

또한 박싱, 언박싱이 일어나기 때문에 성능이 저하가 되게 된다.

따라서 제네릭을 사용할 경우 미리 사용할 데이터를 지정하여 가져와야 성능 저하가 덜 할 수 있다.

0개의 댓글