delegate
키워드로 선언
한정자 delegate 반환형 대리자식별자(매개변수);
인스턴스를 만들 때 함수 식별자를 생성자에 넣어줌.
이 때, 아래 두 개가 같아야함.
인스턴스에 메소드를 연결할 때는 두 가지 방법이 있음
대리자 인스턴스 DelgInstance1
, DelgInstance2
를 호출하면 메소드 Add
, Multiply
가 호출됨.
class Program
{
delegate int Delg(int a, int b);
static int Add(int x, int y){
return x+y;
}
static int Multiply(int x, int y){
return x*y;
}
static void Main(string[] args)
{
Delg DelgInstance1;
DelgInstance1 = new Delg(Add); // 생성자 호출로 대입
int result1 = DelgInstance1(5, 3);
Console.Write(result1); // 8
Dleg DelgInstance2;
DelgInstance2 = Multiply; // 생성자 없이 직접 대입
int result2 = DelgInstance2(5, 3);
Console.Write(result2); // 15
}
}
class Program
{
delegate string GetSound(int reps);
static string Gorani(int reps)
{
string sound = "kaawawaak ";
string res = "";
for (int i = 0; i < reps; i++) res += sound;
return res;
}
static string Cat(int reps)
{
string sound = "yaong ";
string res = "";
for (int i = 0; i < reps; i++) res += sound;
return res;
}
static void PrintSound(GetSound SoundGetter, int reps)
{
string str = SoundGetter(reps);
Console.WriteLine(str);
}
static void Main(string[] args)
{
PrintSound(new GetSound(Gorani), 2); // kaawawaak kaawawaak
PrintSound(new GetSound(Cat), 3); // yaong yaong yaong
}
}
그냥 <T\>
붙어있음.
IComparable<T>
를 상속받은 클래스는 a.CompareTo(b)
메소드를 구현함.
a>b이면 1
a=b이면 0
a<b이면 -1
class Program
{
delegate T Get<T>(T a, T b); // a와 b는 같지 않다고 가정
static T GetBig<T>(T a, T b) where T : IComparable<T>
{
return (a.CompareTo(b)) == 1 ? a : b;
}
static T GetSmall<T>(T a, T b) where T : IComparable<T>
{
return (a.CompareTo(b)) == 1 ? b : a;
}
static void Main(string[] args)
{
Get<int> X = GetBig<int>;
Console.WriteLine(X(5,3)); // 5
Get<float> Y = GetSmall<float>;
Console.WriteLine(Y(5.3f, 3.5f)); // 3.5
}
}
대리자 하나가 여러 개의 메소드를 참조하게 하는 방법
체인 결합 방법 (추가)
+=
, +
연산자.Combine
메소드체인 끊기 방법 (제거)
-=
연산자.Remove
메소드namespace Program
{
delegate void Delg(int a, int b);
class Program
{
static void Add(int a, int b)
{
Console.WriteLine(a + b);
}
static void Subtract(int a, int b)
{
Console.WriteLine(a - b);
}
static void Multiply(int a, int b)
{
Console.WriteLine(a * b);
}
static void Divide(int a, int b)
{
Console.WriteLine(a / b);
}
static void Main(string[] args)
{
Delg DelgInstance = Add;
DelgInstance += Subtract;
DelgInstance += new Delg(Multiply) + new Delg(Divide);
DelgInstance(5, 3); // 8 2 15 1
Console.WriteLine("-----");
DelgInstance -= Subtract;
DelgInstance -= Multiply;
DelgInstance = (Delg)Delegate.Remove(DelgInstance, new Delg(Divide));
DelgInstance(5, 3); // 8
Console.WriteLine("-----");
DelgInstance = (Delg)Delegate.Combine(DelgInstance, new Delg(Subtract));
DelgInstance(5, 3); // 8 2
}
}
}
이름없는 익명 메소드를 대리자 인스턴스에 연결하여 사용 가능
class Program
{
delegate void Delg(int x);
static void Main(string[] args)
{
Delg multiplyTwo = delegate (int a)
{
Console.WriteLine(a * 2);
};
multiplyTwo(53); // 106
}
}
대리자를 event한정자로 수식
delegate void EventHandler(int a);
class Program
{
public event EventHandler Handler;
}
이벤트가 선언된 클래스 밖에서
public delegate void EventHandler(object? sender, EventArgs e);