본문 바로가기
프로그래밍 이야기/GameDev

[C#] Delegate, Event

by Mulder5 2020. 11. 26.
반응형

이제 함수도 파라미터로 넘겨보자. 함수의 유연성, 확장성!

Delegate를 통해서 함수조차도 변수로 만들 수 있다. 즉 변수를 함수의 파라미터로 전달하는 것처럼, 함수도 Delegate를 통한 변수화를 통해 매개변수로 전달이 가능하다. 이로 인한 함수의 활용성과 확장성이 놀랍게 향상 된다. 

Delegate의 기본 형태

delegate [리턴 타입] [함수 대리자 이름] (매개변수 ...) 
delegate int DelegateExample(int a, int b);
int Sum(int a, int b)
{
	return a + b;
}

사용하고자 하는 함수 Sum()이 있다. 이 함수의 형태(리턴타입, 매개변수)를 그대로 delegate 선언에 맞춰준다. 

 

Delegate의 사용 방법

기본 선언 방법

DelegateExample de = DelegateExample(Sum); 

간략한 선언

DelegateExample de = Sum;

익명 함수 선언

DelegateExample de = delegate(int a, int b)
{
	Console.WriteLine("a + B = " + (a + b) );
}

람다식 선언

DelegateExample de = (a, b) => { 
	Console.WriteLine("a + b = " + (a+b));
}

 

Delegate를 매개변수로 사용하기

delegate void delegateFunc();

class MessageProcess
{
    delegateFunc CallOkFunc;
    delegateFunc CallCancelFunc;

    public void Message(string msg, delegateFunc okFunc, delegateFunc cancelFunc)
    {
        //함수 대리자 설정
        CallOkFunc = okFunc;
        CallCancelFunc = cancelFunc;

        // 사용자 입력 선택
        Console.WriteLine("Message : " + msg + " (0: Ok, 1: Cancel)");

        string inputString = Console.ReadLine();

        // 분기 -> 호출
        if(inputString.Equals("0"))
        {
            CallOkFunc();
        }
        else if(inputString.Equals("1"))
        {
            CallCancelFunc();
        }

    }

}


class Program
{
    static void CallOK()
    {
        Console.WriteLine("CallOk");
    }

    static void CallCancel()
    {
        Console.WriteLine("CallCancel");
    }


    static void Main(string[] args)
    {
        MessageProcess msg = new MessageProcess();

        // 사용자 입력을 받아 CallOK와 CallCancel를 분기 호출한다.
        // 함수 이름을 매개변수로 전달!
        msg.Message("Delegate Ex", CallOK, CallCancel);
    }
}

 

Delegate와 Event

event 는 Delegate 와 매우 흡사하나 다음과 같은 차이가 있다.
1. 할당 연산자(=)를 사용하지 않는다. > (+=, -+ 연산자 사용.
2. 클래스 외부에서 event로 선언된 함수를 호출할 수 없다.
3. 클래스 멤버 필드에서 사용가능하다.

public delegate void delegateEvent(string msg);

class InDelegate
{
    public delegateEvent myDelegate;

    // event 키워드는 delegate 타입 앞에 사용한다.
    public event delegateEvent myEvent;

    // event는 Public이라 하더라도 직접 접근이 안되므로 함수로 만들어준다.
    public void DoEvent(int a, int b)
    {
        if(null != myEvent)
        {
            myEvent("DoEvent : " + (a + b));
        }
    }
}

class Program
{
    static void ConsolePrint(string msg)
    {
        Console.WriteLine("Console Print : " + msg);
    }

    static void Main(string[] args)
    {
        InDelegate inDelegates = new InDelegate();

        inDelegates.myDelegate = ConsolePrint;

        // 대입 연산자 사용 불가능
        //inDelegates.myEvent = ConsolePrint;
        inDelegates.myEvent += ConsolePrint;

        inDelegates.myDelegate("MyDelegae Call");

        // 멤버 이벤트는 직접 호출 불가능
        //inDelegates.myEvent("myEvent Call");

        inDelegates.DoEvent(3, 5);


    }
}

 

반응형