반응형

출처: https://coderzero.tistory.com/entry/%EC%9C%A0%EB%8B%88%ED%8B%B0-C-%EA%B0%95%EC%A2%8C-15-%EC%A0%9C%EB%84%A4%EB%A6%AD-Generics

1. 제네릭 타입(Generic Type)

1.1 제네릭이란?

 

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

 

그림. 기능이 동일한 클래스들

 

 

이때 매개변수를 일일히 넣어서 클래스나 인터페이스, 메서드를 만들지 않고, 제네릭 타입(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, Dictionary, LinkedList 등이 있습니다.

 

 

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; 
    } 
}

 

반응형

+ Recent posts