피호출자가 다시 호출자의 메서드를 호출하는 것을 '콜백(callback)'이라고 하고 그러한 메서드를 콜백 메서드라고 한다.
호출자 자신의 인스턴스를 인자로 넘겨준다.
class Program
{
class Person
{
public void See(string s)
{
Console.WriteLine(s);
}
public void Handle()
{
Dog dog = new Dog();
dog.Stroke(this);
}
}
class Dog
{
public void Stroke(Person person)
{
person.See("Smile");
}
}
static void Main(string[] args)
{
Person person = new Person();
person.Handle();
}
}
가장 단순하고 구현하기 편한 방식이다.
하지만 피호출자에게 불필요하게 많은 정보를 제공하게 되고 강한 결합을 형성하기 때문에 좋은 구현은 아니다.
델리게이트에 호출할 메서드를 담아 인자로 넘겨준다.
class Program
{
class Person
{
public void See(string s)
{
Console.WriteLine(s);
}
public void Handle()
{
Dog dog = new Dog();
dog.Stroke(new SeeDelegate(See));
}
}
class Dog
{
public void Stroke(SeeDelegate seeDelegate)
{
seeDelegate("Smile");
}
}
delegate void SeeDelegate(string s);
static void Main(string[] args)
{
Person person = new Person();
person.Handle();
}
}
델리게이트 변수는 여러 메서드를 담을 수 있기 때문에 한 번의 호출에 여러 메서드를 실행하고 싶을 때 유용하다.
호출할 메서드를 인터페이스에 담아 인자로 넘겨준다.
class Program
{
interface ISee
{
void See(string s);
}
class Person : ISee
{
public void See(string s)
{
Console.WriteLine(s);
}
public void Handle()
{
Dog dog = new Dog();
dog.Stroke(this);
}
}
class Dog
{
public void Stroke(ISee seeInterface)
{
seeInterface.See("Smile");
}
}
delegate void SeeDelegate(string s);
static void Main(string[] args)
{
Person person = new Person();
person.Handle();
}
}
실제로 Array.Sort와 같은 닷넷에서 제공하는 수많은 메서드가 이와 같이 구현되었다.
콜백을 구현할 때 delegate와 interface의 차이
1. delegate는 한 번의 호출로 여러개의 메서드를 호출할 수 있다.
2. interface는 한 번의 호출에 여러개의 선택지를 제공한다.
외부에서 이벤트를 구독하고 피호출자가 이벤트를 실행한다.
class Program
{
class CallbackArg : EventArgs
{
public string argString;
public CallbackArg(string argString)
{
this.argString = argString;
}
}
class Person
{
public void See(object sender, EventArgs arg)
{
Console.WriteLine((arg as CallbackArg).argString);
}
public void Handle()
{
Dog dog = new Dog();
dog.SeeHandler += See;
dog.Stroke();
dog.SeeHandler -= See;
}
}
class Dog
{
public event EventHandler SeeHandler;
public void Stroke()
{
SeeHandler(this, new CallbackArg("Smile"));
}
}
delegate void SeeDelegate(string s);
static void Main(string[] args)
{
Person person = new Person();
person.Handle();
}
}
구독/해지 모델일 경우 이벤트로 콜백 메서드를 구현하는 것이 유용하다.
참고 자료
시작하세요! C# 10 프로그래밍 - 정성태