728x90
함수를 보관하는 통을 만들고(대리자선언) 그 통안에 함수를 넣고
나중에 통을 가져와서 함수를 실행시키는 방식입니다.
void RunB(MyClass c) { ... }
class MyClass
{
int id; //필드
string name;
public void Display() { } //메서드
}
MyClass c = new MyClass();
RunB(c)
Delegate는 위 방법처럼 메서드를 다른 메서드로 전달할 수 있도록 하기 위해 만들어 졌다.
또한 메서드의 리턴값으로 호출자에게 전달 수도 있다. Delegate를 사용해 보자
1. 함수의 매개변수를 delegate로 받아와서 결합도를 낮춘다
namespace DelegateTest
{
// 대리자를 만들어준다.
delegate void Del();
// 매개변수가 없고 반환형이 void형인 메서드만 참조 시킬 수 있다.
class Mng
{
public void Main()
{
// myDel이라는 대리자 객체 생성
Del myDel;
// Print라는 메서드를 참조해준다.
myDel = Print;
// 대리자를 이용한 메서드 호출
myDel();
// 메서드를 참조하는 형식은 여러가지를 지원합니다.
// myDel = new Del(Print);
// myDel = Print;
// myDel += Print;
// -=를 이용하여 뺄 수도 있습니다.
}
public void Print()
{
Console.WriteLine("대리자를 통한 메서드 호출입니다.");
}
}
}
2. 이 통에있는걸 비동기로 실행시킬 수 있다.
BeginInvoke는 delegate와 함께 캡슐화된 예약어입니다.
namespace BeginInvokeTest
{
delegate void myDelegate();
class Program
{
static void Main(string[] args)
{
myDelegate a = Func;
// a를 어떻게 불러올지 결정해보자
// 1. a(); # 메서드 호출
// 2. a.Invoke(); # 메서드 동기적 호출
// 3.a.BeginInvoke(null, null); # 메서드 비동기적 호출
for (int i = 0; i < 3; i++)
{
Console.WriteLine("메인스레드는 이걸 세번 출력해주고 프로그램이 종료될 것이야~");
Thread.Sleep(100);
}
}
private static void Func()
{
// 백그라운드 스레드인지, 스레드풀스레드인지 불 형식으로 출력
Console.WriteLine(Thread.CurrentThread.IsBackground);
Console.WriteLine(Thread.CurrentThread.IsThreadPoolThread);
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i+1);
Thread.Sleep(100);
}
}
}
}
3. 이 통을 Event와 결합시켜서 사용 할 수 있다.
- Delegate가 Event와 결합하게되면 이벤트가 발생시 구독자들에게 이벤트 발생을 알릴 수 있다.(콜백메서드 호출)
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Teacher a = new Teacher();
a.Run();
}
}
// 반환형이 없고 매개변수가 int형인 delegate를
// namespace단에 선언합니다.
public delegate void MyDel(int score);
class Teacher
{
public void Run()
{
// 학생 두명 생성
Student1 stu1 = new Student1();
Student2 stu2 = new Student2();
// 각각의 학생의 Event(Delegate)에 메서드를 구독시킨다.
stu1.Stu1Event += GetScore;
stu2.Stu2Event += GetScore;
stu1.Run();
stu2.Run();
}
private void GetScore(int score)
{
Console.WriteLine(string.Format("당신의 점수는 {0}점 입니다.", score));
}
}
class Student1
{
// 네임스페이스 단에 선언된 Mydel을 이벤트형식으로 선언
public event MyDel Stu1Event;
public void Run()
{
// 콜백메서드 호출
Stu1Event(80);
}
}
class Student2
{
// 네임스페이스 단에 선언된 Mydel을 이벤트형식으로 선언
public event MyDel Stu2Event;
public void Run()
{
// 콜백메서드 호출
Stu2Event(100);
}
}
}
728x90