delegate(델리게이트)
프로그래밍을 하다 보면, 매개변수로 값이 아닌 코드 자체를 넘기고 싶을 때가 있다.
이럴 때 delegate(델리게이트)를 사용하면 좋다.
델리게이트란, 메서드 대리자이다.
델리게이트를 선언하고 그곳에 원하는 메서드를 참조시킬 수 있다.
쉽게 말하면, 박스(델리게이트)를 만들고, 박스 안에 함수를 넣고 나중에 박스를 가져와 함수를 실행시키는 것이다.
델리게이트는 형식(Type)이고, private 또는 protected가 아니면 외부에서 실행시킬 수 있다.
사용 방식
(같은 클래스 안의 델리게이트 사용 방식)
public class DelegateTest : MonoBehaviour
{
delegate void dt(int a);
public void func(int a)
{
Debug.Log(a);
}
private void Start()
{
dt dt1;
dt1 = func;
dt1 += func;
dt1(5);
dt dt2 = new dt(func);
dt dt3 = (a) =>
{
Debug.Log($"func : {a}");
};
dt dt4 = delegate (int a)
{
Debug.Log($"func : {a}");
};
}
}
앞서 말했듯 델리게이트는 Type이므로, 객체를 생성해주어야 한다.
여기서 주의점은, 델리게이트의 반환형식, 매개변수와 함수의 반환형식, 매개변수가 서로 같아야 한다.
델리게이트를 호출하는 방식은 다양한 편이다.
- =을 이용하여 델리게이트에 함수를 넣어준 후 실행
- +=로 넣어준 후 실행
- 객체 생성과 동시에 실행
- 람다식으로 실행
- 무명메서드로 실행
무명 메서드
무명 메서드 (혹은 익명 메서드)란 일회용으로 단순한 문장들로 구성되어 있는 메서드를, 정의하지 않고 실행해주는 기능을 말한다.
무명 메서드를 만들기 위해서는 위와 같이 delegate 키워드와 함께 매개변수와 실행 문장 블럭을 적으면 된다. delegate 뒤의 매개변수는 역시 메서드 원형과 동일한 타입이어야 하며, 실행문장블럭에는 여러 문장들을 쓸 수 있다.
이벤트(event)
이벤트(event)란 클래스 내에서 특정한 상황 발생 시 외부에 알리는 기능이다.
이벤트는 일반적으로 델리게이트와 결합해서 사용하며, 구독/구독해제 방식을 사용한다.
이는 관찰자 디자인 패턴(Observer Design Pattern)이다.
Observer Design Pattern : 구독자(Subscriber)가 공급자(Provider)를 등록하고 공급자(Provider)로부터 알림을 수신하는 데 사용
선언 방식 ↴
public delegate void dEvent(string msg);
public event dEvent _event;
사용 방식 ↴
public delegate void dEvent(string msg);
class DClass
{
public dEvent _delegate;
public event dEvent _event;
public void SetEvent(int a, int b)
{
if (null != _event)
{
_event($"setEvent : {a + b}");
}
}
}
public class Base : MonoBehaviour
{
public void SetMsg(string msg)
{
Debug.Log(msg);
}
private void Start()
{
DClass dClass = new DClass();
dClass._event += SetMsg;
dClass.SetEvent(5, 1);
}
}
event에 함수를 =로 할당하는 것은 불가능하고 위에서 말했듯이 += 구독 방식을 사용한다.
event는 델리게이트와 비슷한 형식을 띄지만 event는 델리게이트와 달리 public으로 선언되어 있어도 외부에서 사용이 불가하다.
즉, 안정성을 올리고 캡슐화를 시킨 델리게이트와 같다고 볼 수 있다.
(event 키워드는 접근 한정자 private와 역할이 같다고 보면 된다.)
용도
델리게이트 - 콜백 용도.
이벤트 - 객체의 상태 변화, 사건의 발생을 알리는 용도.
Action과의 차이
스킬의 쿨타임 UI를 바꿔주기 위해 Delegate와 Action을 사용한 예시이다.
Action은 Delegate에 비해 선언과 사용이 간단하고,Delegate는 Action에 비해 조금 더 번거로운 대신, 선언을 하는 과정에서 매개변수의 이름과 event의 이름을 지정해줄수 있고, Invoke 시킬때에도 이름을 지정하고 사용할 수 있으므로
내가 선언한 Delegate가 어떤 목적으로 존재하는지 명확하게 알 수 있다. 즉, 가독성이 더 좋아지는 것이다.
개인의 취향에 맞게 또는 상황에 맞게 사용하면 좋을 것 같다.
'C# 기초' 카테고리의 다른 글
[C#] 리플렉션 - Activator.CreateInstance (0) | 2024.04.21 |
---|---|
[C#] 배열, 리스트, 딕셔너리 (Array, List, Dictionary) (1) | 2023.12.11 |
[C#] async와 await 키워드 그리고 코루틴(Coroutine)과의 차이 (0) | 2023.10.31 |
[C#][개념] 스레드와 동기/비동기 (0) | 2023.10.31 |
[C#] dynamic과 default 키워드 (1) | 2023.10.30 |