본문 바로가기

프로그램/유니티 C# 강좌

[유니티 C# 강좌] 15. 제네릭 (Generics)

728x90
반응형

1. 제네릭 타입(Generic Type)

1.1 제네릭이란?

 

보통 클래스나 인터페이스, 메서드를 사용할 때, 동일한 기능을 수행하지만, 입력하는 데이터 형식만 틀린 경우가 있습니다.

 

코더제로 유니티 C# 강좌 제네릭 (Generics) 기능이 동일한 클래스들
그림. 기능이 동일한 클래스들

 

 

이때 매개변수를 일일히 넣어서 클래스나 인터페이스, 메서드를 만들지 않고, 제네릭 타입(Generic Type)을 사용하여 만들 수 있습니다.

 

동일한 기능을 하는 메서드

제네릭 메서드

void Swap(ref int x, ref int y)
{
    var temp = y;
    y = x;
    x = temp;
}

void Swap(ref float x, ref float y)
{
    var temp = y;
    y = x;
    x = temp;
}
void Swap<T>(ref T x, ref T y)
{
    var temp = y;
    y = x;
    x = temp;
}

 

제네릭이란 형식 매개변수(Type parameter)입니다.

형식 매개변수를 사용해서 클래스나 메서드를 만들게 되면, 그 클래스나 메서드를 호출하기 전까지 데이터 형식 지정을 연기 할 수 있습니다.

 

 

1.2 제네릭 특징

 

 ● 코드 재사용성이 높습니다.

 ● 성능이 좋습니다. (런타임 때 데이터 형식이 결정 되는 것이 아니라, 코드에서 호출 할때 데이터 형식이 결정되기 때문에 성능 저하가 없습니다.)

 

 

2. 제네릭 클래스(Generic Class)

2.1 사용 방법

 

멤버변수의 타입을 미리 결정하지 않고, 사용할 때 제넥릭 클래스를 사용합니다.

 

사용방법 : 제네릭 클래스
public class 클래스-이름<T> 
{ public T ... }

 

using UnityEngine; 

public class GenericsClassExample : MonoBehaviour 
{ 
    public class GenericsClass<T>
    { 
        private T m_Value; 

        public GenericsClass(T value) 
        { 
            m_Value = value; 
        } 

        public void Method1() 
        { 
            Debug.Log(m_Value); 
        } 
    } 

    void Start() 
    { 
        GenericsClass<int> m_GenericsClass1 = new GenericsClass<int>(5); 
        m_GenericsClass1.Method1(); // 출력 : 5 
        GenericsClass<float> m_GenericsClass2 = new GenericsClass<float>(5.1f); 
        m_GenericsClass2.Method1(); // 출력 : 5.1 
    } 
}

 

 

2.2 C# 제네릭 클래스

 

C#는 기본적으로 제공하는 제네릭 클래스가 많습니다.

대표적인 것이 List<T>, Dictionary<T>, LinkedList<T> 등이 있습니다.

 

 

2.3 제네릭 타입 제약 (Type Constraint)

 

제네릭 타입을 선언할 때 제약 조건을 걸 수 있습니다.

 

사용방법은 제네릭 선언 후 where T : 제약조건 과 같은 식으로 where 뒤에 제약 조건을 붙이면 됩니다.

 

2.3.1 new 제약 조건

 

new 제약 조건은 제네릭 클래스 선언의 형식 인수에 공용 매개변수가 없는 생성자가 있어야 함을 지정합니다. 

 

사용 방법 : 제네릭 new 타입 제약1

class Class1<T> where T : new() // T는 디폴트 생성자를 가져야 함

 

다른 제약 조건과 함께 new() 제약 조건을 사용하는 경우 마지막에 지정해야 합니다.

 

사용 방법 : 제네릭 new 타입 제약2
class Class1<T> where T : IComparable, new() // T는 디폴트 생성자를 가져야 함

 

 

2.3.2 형식에 대한 조건

 

사용 방법 : 제네릭 형식에 대한 조건

class Class1<T> where T : struct // T는 Value 타입임
class Class2<T> where T : class // T는 Reference 타입임
class Class4<T> where T : Class3 // T는 Class3의 파생클래스어야 함
class Class4<T> where T : IComparable // T는 IComparable 인터페이스를 가져야 함.
class Class5<T, U>  // 복수 타입의 매개변수 제약
    where T : class
    where U : struct
{ }

 

 

3. 제네릭 메서드

 

매개변수의 타입을 미리 결정하지 않고, 사용시 결정하는 것입니다.

 

사용방법 : 제네릭 메서드

T 메소드-이름<T>(T arg)
{
    T temp = arg;
    //...
    return temp;
}

 

using UnityEngine; 

public class GenericExample : MonoBehaviour 
{ 
    void Start() 
    { 
        int iX = 1, iY = 2; 
        Swap(ref iX, ref iY); 
        Debug.LogFormat($"x = {iX} y = {iY}"); // 출력 : x = 2 y = 1  

        string sX = "ab", sY = "cd"; 
        Swap(ref sX, ref sY); 
        Debug.LogFormat($"x = {sX} y = {sY}"); // 출력 : x = cd y = ab  
    } 

    void Swap<T>(ref T x, ref T y) 
    { 
        var temp = y; 
        y = x; 
        x = temp; 
    } 
}

 

728x90
반응형