목록

델리게이트와 이벤트

게임 개발 시 콜백함수를 많이 사용하게 되는데, 이것의 근간이 되는 기본개념들을 정리해 놓으려고 한다.


#델리게이트

  • 기본

    1. 델리게이트의 본질은 메서드를 다룰 수 있는 참조형 이다.
    2. 복수 또는 단일 메서드를 대신하여 호출하는 역할을 한다 -> 같은 형식이어야 한다.(매개변수나 리턴형)
    3. 외부에서 호출 가능.(private, protected메서드는 호출 불가)
  • 델리게이트 형식

    1. [접근 한정자] delegate return형 델리게이트형명(메서드 매개변수);
    2. delegate int DelegateType(string Name); -> DelegateType자체가 타입명이 된다.
  • 델리게이트 사용

    1. DelegateType DelegateMethod = new DelegateType(Function); (초기버전에는 new로 생성)
    2. 요즘에는 DelegateType DelegateMethod = Function;으로 사용
  • 예시

    namespae ConsoleApplication1
    {
    //델리게이트 선언
    delegate void DelegateType(string str);
    
    class A
    {
      public void printf(string str)
      {
        Console.WriteLine(str);
      }
    }
    
    class Program
    {
      static void Main(string[] args)
      {
        A = Test = new A();
        //첫번쨰 방식 델리게이트 등록 방법.(C# 1.0이상에서 사용 가능)
        DelegateType DelMethod1 = new DelegateType(Test.Print);
        DelMethod1("Hello World1"); //printf함수 호출
    
        //두번째 방식 델리게이트 등록 방법.(C# 2.0이상에서 사용 가능)
        DelegateType DelMethod2 = Text.Print;
        DelMethod1("Hello World2"); //printf함수 호출
      }
    }
    }

#멀티캐스트 델리게이트

  • 멀티캐스트

    • 데이터를 여러 사용자에게 동시에 보낸다.
  • 델리게이트 조합

    • 다수 또는 단일 메서드 호출
    • +=, -= 호출할 메서드 포함 또는 제

예시

class A
{
  public void PrintA(string str)
  {
    Console.WriteLine("PrintA");
  }

  public void PrintB(string str)
  {
    Console.WriteLine("PrintB");
  }
}

class Program
{
  static void Main(string[] args)
  {
    A = Test = new A();
    //델리게이트 등록
    DelegateType DelFunc = Text.PrintA;
    //델리게이트 추가
    DelFunc += Test.PriontB;
    DelFunc();  //PrintA, PriontB 호출.
    //델리게이트 삭제
    DelFunc -= Test.PriontB;
    DelFunc();  //PrintA만 호출.
  }
}

#이벤트(event)

  • 의미

    • 사전, 특정 상황이 발생했을 떄 알리고자 하는 용도(호출을 의미 + 데이)
    • 이벤트를 발생시키는 클래스를 게시자라 하고
    • 이벤트를 받거나 처리하는 클래스를 구독자라 한다.
    • 델리게이트를 기반으로 한다.(메서드 호출)
    • 이벤트와 델리게이트의 차이점은 이벤트는 public으로 선언되어 있어도 외부에서 사용할 수 가 없다.
    • 이벤트는 메서드 안에서만 사용가능!!
  • 형식

    • [접근 한정자] event 델맄게이트형 이벤트명 (델리게이트기반이므로 미리 형식이 잡혀 있다.)
  • 예시

    //델리게이트 형식 정의
    delegate void DelegateType(string message);
    classA
    {
    //이벤트 핸들러 선언
    public event DelegateType EventHandler;
    
    public void Func(string Message)
    {
      //메서드 안에서만 사용가능!!
      EventHandler(Message);
    }
    }
  • 사용이유(?)(내 생각)

    • 그냥 델리게이트와 차이점이 별로 없어 보인다. 하지만 정의된 클래스 메서드 안에서만 사용가능하므로. 델리게이트로 내부로만 쓸 콜백함수 만들 떄 private로 선언했다면 외부에서 등록가능하도록 추가,삭제 함수를 만들어야하는데… 이벤트 함수를 쓰면 public으로 선언해도 외부에서 호출 못하므로.(등록 삭제는 외부에서 가능.)
  • 이벤트에 메서드 추가 및 삭제

    • 객체.이벤트핸들러 += 객체.메서드1;
    • 객체.이벤트핸들러 += 객체.메서드2;2
    • 객체.이벤트핸들러 -= 객체.메서드1;
  • 이벤트의 핵심

    • 이벤트 핸들러에 객체의 메서드를 연결
    • 이벤트 핸들러는 객체 메서드에서 호출
    • 이벤트 핸들러를 포함하는 객체 안의 메서드를 통해 다른 객체 또는 같은 객체의 메서드를 호출하기 위한 방법(같은 데이터 전달)
델리게이트 이벤트
공통점 : 객체의 메서드 호출 객체의 메서드 호출
차이점 : 델리게이트로 호출 이벤트를 포함한 메서드에서 호출
델리게이트로 연결 이벤트 핸들러에 연결

출처 : https://www.youtube.com/watch?v=B-yaWp900sQ


#Action과 Func

람다 식을 위한 전용 델리게이트 로서, 델리게이트의 일일이 정의해야 한다는 불편함을 없애기 위해 마소에서 델리게이트의 형식을 제네릭의 도움으로 일반화해서 BCL에 Action과 Func로 포함시켰다.

public delegate void Action<T>(T obj);
//--> 반환값이 없는 델리게이트로서 T 형식 매개변수는 입력될 인자 1개의 타입을 지정

public delegate TResult Func<TResult>();
//--> 반환갑이 있는 델리게이트로서 TResult 형식 매개변수는 반환될 타입을 지정

Action과 Func의 차이는 반환값의 유무에 있다.

또한, 마소에서는 이러한 Action과 Func의 인자를 16개까지 받을 수 있도록 미리 정의해놨다.

Action

  • Action은 반환값과 인자값이 없는 함수 포인터 ( 델리게이트 )
  • 반환 형식이 없음
  • 어떤 결과를 반환하는것을 목적으로 하지 않으며, 일련의 작업 수행을 목적

    Action<string> logOut = (txt) =>
    {
    Console.WriteLin(DateTime.Now + ": " + txt);
    };

Fucn

  • 반환값과 인자값이 있는 함수 포인터 ( 델리게이트 )
  • 반환 형식이 있음
  • 인자 값 넣는다면 Func<인자1, 인자2, …, 반환>형식

    //처음 두 int, int 타입은 인자 두개에 대응되고, 마지막 int 타입은 반환값에 대응
    Func<int, int, int> myFunc = (a, b) => a + b;
    Console.WriteLine("10 + 2 == " + myFunc(10, 2));  //출력 결과 : 10 + 2 == 12