[C#] 델리게이트

1. 델리게이트 

C++의 메서드포인터같은 놈이다 (물론 델리게이트가 더 엄격하고 객체지향에 부합한다)
델리게이트는 말 그대로 대리자로서 메서드를 델리게이트에 등록하면
델리게이트를 통해서 메서드를 대신 호출할 수 있다.
언듯 보면 삽질같지만 메서드의 인자로 메서드를 넘겨주는 듯한 기능을 구현하거나
런타임에서 필요한 동작을 델리게이트에 등록해두고
델리게이트 하나로 복수의 메서드를 한꺼번에 호출(이를 델리게이트 체인이라 한다)
할 수 있는 등 다양한 사용법이 있다.

특히 게임개발에서 싱글톤을 사용할 때 유용한데,
싱글톤클래스에 델리게이트를 선언해둔 뒤에
각각 산개되어있는 다른 오브젝트들의 스크립트에서 싱글톤 인스턴스의 델리게이트에
특정 상황에서 발생할 수 있는 동작들을 할당해주면
델리게이트를 이용해서 손쉽게 호출할 수 있다.

예를들어 캐릭터, 맵, UI등 각각의 게임오브젝트들이 자신만의 스크립트를 갖고있고
게임을 1회 진행한 뒤에 이들을 다시 초기화 하기 위해서는 일일이 각각의 스크립트들이
게임의 상황을 체크하며, 자신이 갖고있는 초기화 루틴을 실행해줘야 하지만,

싱글톤으로 만들어둔 매니저 클래스에서'만' 게임의 상태를 체크하며
게임의 초기화가 필요하면 각 게임오브젝트의 초기화 메서드를 갖고있는 델리게이트만
실행해주면 모든 게임오브젝트의 초기화루틴을 일괄적으로 실행할 수 있다.

델리게이트의 대략적인 사용방법은 아래와 같다  



/* 델리게이트는 메서드를 선언하는 것과 동일하지만 
참조를 선언하여 new키워드를 이용해서 인자 값으로 메서드명을 할당해준 뒤 
델리게이트를 사용할 때는 메서드를 사용하는 것 처럼 사용하면 된다.
델리게이트에 등록할 메서드는 델리게이트와 동일한 리턴타입과 형식매게변수를 가져야 한다. 
*/
namespace TestArea
{
  delegate void DelegateName(string value1, int value2);

  class DelegateTest
  {
    void Method1(string name, int age)
    {
      Console.WriteLine("내 이름은 {0}이고 {1}살 입니다", name, age); 
    }

    void Method2(string location, int time)
    {
      Console.WriteLine("이곳은 {0}이고 지금은 {1}시 입니다", location, time);
    }
  }

  class MainApp
  {
    static void Main(string[] args)
    {
      DelegateName testDelegate;
      
      DelegateTest methodContainClass = new DelegateTest();
      
      // 델리게이트 체인. 2개의 메서드가 testDelegate에 등록된다.
      testDelegate += methodContainClass.Method1;
      testDelegate += methodContainClass.Method2;

      // 아래 두 코드는 위의 +=를 이용한 것 2줄의 코드와 동일한 동작을 수행한다
      //testDelegate = new DelegateName( methodContainClass.Method1) + new DelegateName( methodContainClass.Method2); 
      //testDelegate = (DelegateName) Delegate.Combine( new DelegateName(methodContainClass.Method1), new DelegateName( methodContainClass.Method2))

      testDelegate("Alpha", 20);
      // 출력결과: 
      /* 내 이름은 Alpha이고 20살 입니다
         이곳은 Alpha이고 지금은 20시 입니다 
       */

      // 델리게이트 체인에서 Method2를 제거한다 
      testDelegate -= methodContainClass.Method2;

      testDelegate("Sara", 15);
      // 출력결과: 내 이름은 Sara이고 15살 입니다 
    }
  }
}



댓글

가장 많이 본 글