공부/Unity

[Unity] 제네릭, delegate, lambda

굴러다니다니 2025. 5. 23. 15:12

제네릭

로직은 같은데 데이터 타입만 다를 때 사용

제네릭타입은 지정한 타입으로 변환되어 코드가 자동으로 만들어진다

 

숫자 a와 b의 값을 바꾸는 Swap 함수를 만들었는데, int형, float형 둘 다 가능하게 만들고 싶다면

제네릭 타입인  <T>로 지정해 자동으로 타입이 변환된다

 

void 함수명<제네릭명> ,,,  where 제네릭명 : struct:

제네릭의 타입 조건을 달 수 있다. (인터페이스, 부모클래스, struct, class, new())

where문은 생략이 가능하다

 

제네릭명은 T가 아니라 원하는대로 쓰면 된다

 


대리자

delegate, event, lambda

 

delegate: 함수를 저장하는 데이터 타입 정의

delegate 리턴타입 델리케이트명(파라미터)

 

위에 두 줄: 데이터 타입 정의

아래 두 줄: 변수 선언

MyDelegate는 void f(int) 형식만 저장

MyDelegate2는 void f(int, int)형식만 저장

델리게이트를 함수처럼 호출하면 저장된 OnClick 함수가 호출된다

+= 를 사용해 함수 여러개 저장할 수 있고, 이를 델리게이트를 한 번 호출할때 저장된 함수 모두 호출된다

-=로 삭제 가능

 

event

const를 변수에 추가하면 상수가 되는 것 처럼 event를 델리게이트에 추가하면 event가 된다

event는 아예 리셋하거나 새롭게 정의할 수 없다.

c.myEvent = OnClick / c.myEvent(1) 은 에러

 


lambda : 이름 없는 함수

딱 한 번 쓸 함수인데 작명하고싶지 않다면 사용

 

(파라미터) => {명령문} 으로 사용한다

변수 캡쳐

내부에 없는 외부의 변수를 가져와 사용할 수 있다

for (int i = 0; i < 3; ++i)
{
    myDelegate += (a) =>
    {
        print($"a{a} i:{i}");
    };
}
myDelegate(1);

변수 캡쳐를 할 때는 value type이 아닌 ref type으로 참조를 가져오기때문에

myDelegate(1)이 실행되었을 때의 i값인 3이 i에 들어가 출력되고, 매개변수로 받은 a값 1이 출력된다

 

for (int i = 0; i < 3; ++i)
{
    int b = i;
    myDelegate += (a) =>
    {
        print($"a{a} i:{b}");
    };
}
myDelegate(1);

만약 i값만큼 변하게 만들고 싶다면 로컬 변수를 따로 선언해, 반복할 때마다 b가 생성되어 독립적으로 변수를 캡쳐해 찍을 수 있다

 

delegate의 함수 형식이 바뀌면 매번 새롭게 정의해야하기때문에, 제네릭을 이용한다

Action은 리턴타입이 없는 함수 (지정할 수 없음)

Function은 리턴타입이 있는 함수 (지정할 수 있음)

 


* 활용

배열의 몇번째에 데이터가 있는지 찾고싶을 때

using System;
using UnityEngine;

public class Practice8 : MonoBehaviour
{
    int[] array = { 1, 3, 2, 4 };
    private void Start()
    {
        Debug.Log(FindIndex(array, 3));

        Debug.Log(Array.IndexOf(array, 3));

        Debug.Log(Array.FindIndex(array, a => a == 3));
    }

    int FindIndex(int[] arr, int v)
    {
        for (int i = 0; i < arr.Length; i++)
        {
            if (arr[i] == v) return i;
        }

        return -1;
    }

}

3가지 방법을 쓸 수 있지만 2가지는 내장 함수를 썼다

Array.FindIndex(배열, a => a == 찾으려는 값); 으로 쓸 수 있다

728x90
반응형