콘텐츠로 건너뛰기
Home » 델리게이트 (Delegate) 콜백, 체인

델리게이트 (Delegate) 콜백, 체인

  • by
델리게이트 (Delegate) 콜백, 체인

델리게이트 (Delegate)

해석하면, 대리인 이라는 뜻의 델리게이트는 메소드를 참조하는 변수이다.
C++의 함수 포인터와 비슷하기 때문에 C++를 공부한 사람이라면 어렵지 않게 이해할수 있겠지만, 그렇지 않은 사람들을 위해 간단한 개념을 설명해 본다.

대리라는 말은 보통 내가 해야할 일을 다른 누군가에 위임하는 것을 말한다.

부모님의 심부름을 동생에게 시킨다든지, 배가 고플때 동생에게 라면을 끓이게 한다던지 어쨋든 프로그래밍에서도 이런 대린의 역할을 해주는 변수가 존재하는데, 그것이 바로 델리게이트(Delegate) 이다.

델리게이트는 메소드를 대신해서 호출하는 역할을 한다. (메소드 대리인)

지금까지는 특정 메소드를 처리할 때 그 메소드를 직접 호출해서 실행 시켜야 했지만, 델리게이트를 사용하면 그 메소드를 대신하여 호출할수 있다.

그럼 이제 델리게이트가 코드상에서 어떻게 쓰이는지 구체적으로 살펴보자.

델리게이트 선언과 참조

델리게이트로 특정 메소드를 대신 호출하기 위해서는

(1) 우선 그 메소드와 동일한 타입의 델리게이트 타입을 선언해야 합니다.

//delegate 반환타입 델리게이트이름 (매개변수)
delegate void typeA(void); // void funcA(void)
delegate void typeB(int); //void funcB(int)
delegate float typeC(float); // float func(float)
delegate string typeD(int); //string funcD(int)

메소드 타입은 매개변수와 반환타입에 의해 결정되기 때문에, 델리게이트 타입도 그 메소드와 동일한 매개변수, 반환타입으로 선언해주면 된다.

(2) 그리고 선언한 델리게이트 타입으로 델리게이트 변수를 생성한다, 생성한 델리게이트 변수에 해당 메소드를 참조시킨다.

// delegate 변수 생성
typeA delegate0;
typeB delegate1;
typeC delegate2;
typeD delegate3;

// 메소드 참조
delegate0 = new typeA(funcA);
delegate1 = new typeA(funcB);
delegate2 = new typeA(funcC);
delegate3 = new typeA(funcD);

여기까지하면 이제 델리게이트 변수로 해당 함수를 호출할수 있게 됩니다.

그럼 직접 프로그램을 작성해 봅시다.

namespace delegate_Test {
    delegate int MtDelegate(int a, int b);
    class MainApp {
        public static int Plus(int a, int b) {
            return a + b;
        }
        public static int Minus(int a, int b) {
            return a - b;
        }
        static void Main(string[] args) {
            MyDelegate calculate;
            calculate = new MyDelegate(Plus);
            int sum = calculate(11, 22);
            Comsole.WriteLine("11 + 22 = {0}", sum);
            calculate = new MyDelegate(Minus);
            Comsole.WriteLine("22 - 11 = {0}", calculate(22, 11));
        }
    }
}

콜백 메서드

사실 위의 예제와 같이 델리게이트를 사용하는것에는 큰 의미가 없습니다.

메소드를 직접 호출하면 되지, 굳이 델리게이트를 참조해서 쓸 필요가 없기 때문입니다.

델리게이트의 진정한 가치는 콜백메서드 를 구현 할때에 나타납니다.

콜백(Callback)이란 A라는 메서드를 호출할때에 B라는 메서드를 넘겨주어 A 메서드로 하여금 B 메서드를 호출하도록 하는 것을 말하며, 이때의 A 메서드를 콕백메서드라고 합니다.

이 과정에서 델리게이트는 B메서드를 참조하는 변수로써 A메서드에게 넘겨지는 매개변수가 되고, A 메서드는 매개변수로 받은 델리게이트로 B메서드를 호출합니다.

다음 예제를 봅니다.

namespace delegate_Test {
    delegate int MtDelegate(int a, int b);
    class MainApp { // 계산기 함수
        public static void Calculator(int a, int b, MyDelegate dele) {
            Console.WriteLine(dele(a, b));
        }
        public static int plus(int a, int b) {
            return a + b;
        }
        public static int minus(int a, int b) {
            return a - b;
        }
        public static int multply(int a, int b) {
            return a * b;
        }
        static void Main(string[] args) {
            MyDelegate Plus = new MyDelegate(plus);
            MyDelegate Minus = new MyDelegate(minus);
            MyDelegate Multply = new MyDelegate(multply);
            Calculator(11, 22, Plus);
            Calculator(33, 22, Minus);
            Calculator(11, 22, Multply);
        }
    }
}

위의 예제를 보면 계산기 함수를 호출할 때마다 원하는 연산(메서드)를 넘겨주어 계산기가 해당 기능을 하도록 하고 있습니다.

이렇게 특정 함수가 그때그때마다 지정된 기능을 하도록 하는 것, 이것이 콜백 메서드의 편리함이며, 이는 델리게이트가 있기에 가능한 것입니다.

일반화 델리게이트

위에서 작성한 예제에서는 델리게이트가 참조한 메소드가 int형 뿐이었지만, 델리게이트를 일반화하면 어떤 타입의 메소드든지 참조할수 있습니다.

다음 예제를 봅시다.

namespace delegate_Test {
    delegate T MtDelegate < T > (T a, T b);
    class MainApp { // 계산기 함수
        public static void Calculator<T>(T a, T b, MyDelegate < T > dele) {
            Console.WriteLine(dele(a, b));
        }
        public static int plus(int a, int b) {
            return a + b;
        }
        public static float plus(float a, float b) {
            return a + b;
        }
        public static double plus(double a, double b) {
            return a + b;
        }
        static void Main(string[] args) {
            MyDelegate < int > Plus_int = new MyDelegate<int>(plus);
            MyDelegate < float > Plus_float = new MyDelegate<float>(plus);
            MyDelegate < double > Plus_double = new MyDelegate<double>(plus);
            Calculator(11, 22, Plus_int);
            Calculator(3.3 f, 4.4 f, Plus_float);
            Calculator(5.5, 6.6, Plus_double);
        }
    }
}

어떤 타입의 plus 메소드든지 참조할 수 있도록 델리게이트를 일반화 하였다.

델리게이트 체인

지금까지의 델리게이트는 하나의 델리게이트에 하나의 메소드만을 참조하였다.

하지만 델리게이트는 놀랍게도 여러개의 메소드를 참조할 수 있는 능력자이다.

델리게이트가 여러개의 메소드를 참조하게 하는 방법은 아주 간단하다.

다음과 같이 +,+= 로 새로운 메소드를 추가만 해주면 된다.

MyDelegate del;
del = new MyDelegate(func0);
del += func1;
del += func2;

이제 델리게이트를 호출하면, 참조된 메소드들을 차례대로 호출하게 됩니다.

이렇게 하나의 델리게이트에 여러개의 메소드를 연결시키는 것을  델리게이트 체인  이라 합니다.

그리고 델리게이트에 연결된 메소드를 끊기 원한다면 반대로 -= 를 해주면 됩니다.

namespace delegate_Test {
    delegate void MtDelegate();
    class MainApp {
        public static void func0() {
            Console.Write("첫번째");
        }
        public static void func1() {
            Console.Write(" 두번째");
        }
        public static void func2() {
            Console.Write(" 세번째");
        }
        static void Main(string[] args) {
            MyDelegate dele;
            dele = new MyDelegate(func0);
            dele += func1;
            dele += func2;
            dele(); // 첫번째 두번째 세번째
            Colsole.WriteLine();
            dele -= func0;
            dele -= func2;
            dele(); // 두번째
            Colsole.WriteLine();
        }
    }
}

댓글 남기기