내일배움캠프 27일차 TIL <C# Delegate> 05/16

정광훈(Unity_9기)·2025년 5월 16일

TIL (Today I Learned)

목록 보기
39/101
post-thumbnail

Delegate

델리게이트는 함수를 변수처럼 저장하고 실행

델리게이트 핵심 특징

  • 메서드를 저장하고 나중에 실행할 수 있다
  • +=, -=로 여러 개의 함수 연결 가능 (멀티캐스트)
  • ?.Invoke()로 null 체크 후 안전 실행 가능

ex)

public delegate void TestDel1();
public delegate void TestDel2(int num1);

public TestDel1 testDel1;
public TestDel2 testDel2;

// 델리게이트 넣을 함수들
public void TestFun1()
{Debug.Log("이것은 테스트 펑션1");}
public void TestFun2(int num1)
{Debug.Log("이것은 테스트 펑션2" + num1);}

public void Show1()
{
    testDel1 = TestFun1;
    testDel2 = TestFun2;

    testDel1();
    testDel2(2);
}

Action
사용 및 활용 void 반환 함수에 사용하는 제너릭 델리게이트

기본은 위 코드처럼 사용하지만
Action은 두 줄 쓸 거 한 줄만 쓴다.

결국 이 한 줄이면 해결된다.

public Action testAct1;
public Action<int,int> testAct3;

public void TestFun1()
{Debug.Log("이것은 테스트 펑션1");}

public void TestFun3(int num1, int num3)
{Debug.Log("이것은 테스트 펑션3 " + num1 + num3);}

public void Show1()
{
    testAct1 = TestFun1;
    testAct3 = TestFun3;

    testAct1();
    testAct3(2, 3);
}

Func
사용 및 활용 반환 함수에 사용하는 제너릭 델리게이트

public Func<int> testFun1;
public Func<int, int> testFun2;

(나머지 코드는 변수 이름만 바꾸면 됨)

기존 델리게이트 void 형

public delegate void TestDel1();
public TestDel1 testdel1;
public Action<int> testAct2;

public void TestFun1()
{
	Debug.Log("이것은 테스트 펑션1");
    Debug.Log("이것은 테스트 펑션2 : " + num1);
}
void Start()
{
	testdel1 = TestFun1;
	testdel1(); // 출력: 이것은 테스트 펑션1
    
    testAct2 = TestFun2; // 메서드 연결
	testAct2(2);
}

람다 (void)
// 람다 (매개변수) => {//함수내용};
//action + 람다 + 중괄호 매개변수있는 타입

public Action testAct1;
public Action<int> testAct2;

void Start()
{
	testAct1 += () =>
	{
		Debug.Log("이것은 테스트 펑션1");
	};

	testAct2 += (num1) =>
	{
		Debug.Log("이것은 테스트 펑션2 : " + num1);
	};
    
	testAct2(2);
	testAct1?.Invoke();
}

기존 델리게이트 반환 int

public delegate int TestDelType1();
public delegate int TestDelType2(int num1);

public TestDelType1 testDel1;
public TestDelType2 testDel2;

public int TestFunType1()
{return 7;}

public int TestFunType2(int num1)
{return num1;}

void Start()
{
	testDel1 = TestFunType1;
    testDel2 = TestFunType2;
    
    int result = testDel1();
	int result = testDel2(2);
}

람다 (반환형)

public Func<int> testFun1;
public Func<int, int> testFun2;

void Start()
{
	testFun1 += () => 7;
	testFun2 = (num) => num;

	testFun1 += () => { return 7; };

	int result = testFun1();
	int result = testFun2(2);
}

실습 정리

using System;
using System.Xml.Serialization;
using UnityEngine;

public class Delegate : MonoBehaviour
{
    private void Start()
    {
        Show4();
    }

    // 델리게이트 넣을 함수들
    public void TestFun1()
    { Debug.Log("이것은 테스트 펑션1"); }

    public void TestFun2(int num1)
    { Debug.Log("이것은 테스트 펑션2 " + num1); }

    public void TestFun3(int num1, int num2)
    { Debug.Log("이것은 테스트 펑션3 " + num1 + num2); }

    // 리턴이 있는 함수
    public int TestFunType1()
    { return 7; }
    public int TestFunType2(int num1)
    { return num1; }
    public string TestFunType3(int num1, string text1)
    { return num1 + text1; }

    #region Action

    // 사용 및 활용 void 반환 함수에 사용하는 제너릭 델리게이트
    // Action<매개변수>
    public Action testAct1;
    public Action<int> testAct2;
    public Action<int, int> testAct3;

    public void Show1()
    {
        testAct1 = TestFun1;
        testAct2 = TestFun2;
        testAct3 = TestFun3;

        //"이것은 테스트 펑션1" 출력
        //testAct1();
        //"이것은 테스트 펑션2 3" 출력
        //testAct2(3);
        //"이것은 테스트 펑션3 45" 출력
        //testAct3(4, 5);

        // +=, -= 로 여러 개의 함수 연결 가능(멀티캐스트)
        testAct1 += TestFun1;
        testAct1 -= TestFun1;
        testAct1 -= TestFun1; // 2번 더해지고 2번 빼줬기 때문에 null이 되어 버렸다.

        // 만약 testAct1 델리게이트에 할당된 메서드가 있다면(즉, testAct1이 null이 아니라면),
        // 그 메서드를 실행해라
        testAct1?.Invoke(); // null이라 아무것도 출력이 안 됨
    }

    public void Show3() // 람다
    {
        // 한 번만 쓸건데 함수로 만들기 그럴 때
        // 람다 (매개변수) => {함수내용}
        testAct1 += () =>
        {
            Debug.Log("이것은 테스트 펑션1");
        };

        testAct1(); // "이것은 테스트 펑션1" 출력

        // testAct2 = TestFun2; 를 람다로
        testAct2 = (num) =>
        {
            Debug.Log(num);
        };

        testAct2(5); // "5"

        // testAct3 = TestFun3;
        testAct3 = (num1, num2) =>
        {
            Debug.Log($"{num1} {num2}");
        };

        testAct3(5, 7);  // "5, 7" 출력
    }

    #endregion

    #region Func

    // 사용 및 활용 반환 함수에 사용하는 제너릭 델리게이트
    // Func<매개변수, 반환형>
    public Func<int> testFuncType1;
    public Func<int, int> testFuncType2;
    public Func<int, string, string> testFuncType3;

    public void Show2()
    {
        testFuncType1 = TestFunType1;
        testFuncType2 = TestFunType2;
        testFuncType3 = TestFunType3;

        Debug.Log(testFuncType1()); // "7" 출력
        Debug.Log(testFuncType2(2)); // "2" 출력
        Debug.Log(testFuncType3(3, " 투터")); // "3 투터" 출력
    }

    public void Show4()
    {
        // testFuncType1 = TestFunType1;
        testFuncType1 = () =>
        {
            return 7;
        };

        // testFuncType2 = TestFunType2;
        testFuncType2 = (num) =>
        {
            return num;
        };

        // testFuncType3 = TestFunType3;
        testFuncType3 = (num, text) =>
        {
            return num + text;
        };

        Debug.Log(testFuncType1()); // "7" 출력
        Debug.Log(testFuncType2(2)); // "2" 출력
        Debug.Log(testFuncType3(3, " 투터")); // "3 투터" 출력
    }

    #endregion
}

0개의 댓글