델리게이트는 함수 포인터와 비슷한 개념으로 메서드를 참조하는 형식이다.
메서드를 다른 메소드의 인자로 전달하거나, 메서드를 변수로 저장하거나, 메서드를 이벤트에 연결하는 동작이 가능케 한다.
키워드 delegate
를 사용하여 델리게이트를 정의할 수 있다.
private delegate void Mydelegate(string message);
델리게이트는 컴파일러에 의해 내부적으로 특별한 클래스로 컴파일된다.
모든 델리게이트는 System.Delegate
클래스를 상속받고,
멀티캐스트 델리게이트만이 System.MulticastDelegate
클래스의 하위 클래스이며
여러 개의 메서드를 참조할 수 있다.
멀티캐스트 델리게이트의 자세한 내용은 2편에 있다.
델리게이트는 파라미터 형식과 개수 그리고 반환 타입이 동일한 모든 메서드를 참조할 수 있다.
= (메서드 시그니처가 동일한 모든 메서드)
아래 코드를 보면 메서드 시그니처가 동일한 메서드를 인자로 받는다.
(new 키워드 생략 가능하다.)
private delegate void Mydelegate(string message);
static void WriteMessage(string message)
{ Console.WriteLine(message); }
static void Main(string[] args)
{
Mydelegate mydelegate = new Mydelegate(WriteMessage);
// Mydelegate mydelegate = WriteMessageOnce;
mydelegate("아무거나 한 번 말하기");
// 출력 : 아무거나 한 번 말하기
}
위와 같은 것이 가능한 이유는 메서드의 이름을 전달하면 해당 메서드의 델리게이트가 반환되기 때문이다.
Console.WriteLine(WriteMessage);
// 출력 : System.Action`1[System.String]
이거는 실수로 메서드 이름만 인자로 넣었다가 찾은 것인데,
콘솔로 메서드의 이름을 인자로 놓고 출력해보면 메서드의 델리게이트 정보가 보인다.
쉽게 말해서 메서드의 주소가 전달된다고 생각하면 된다.
델리게이트로 얻을 수 있는 유연성 중 하나는 메서드를 다른 메서드의 인자로 줄 수 있다는 것이다.
public class MyClass
{
public delegate void Mydelegate(string message);
public void ShowSomething(String str, Mydelegate mydelegate)
{
mydelegate(str);
}
}
internal class Program
{
static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.ShowSomething("콜백 메서드 전달",Console.WriteLine);
}
}
시그니처가 맞는 메서드를 전달해서 콜백 매커니즘을 구현할 수 있다.
위 코드에서는 인자가 Object 타입에 반환 타입이 void인 Console.WriteLine을 전달해서 메서드를 호출하는 모습을 볼 수 있다.
참고 자료
예제로 배우는 C# 프로그래밍 : C# delegate의 개념