* 델리게이트
// 대리인이라는 뜻으로 중간에서 메소드를 접근하게 해준다.
namespace ConsoleApplication27
{
delegate int dele(int a, int b);
class class2
{
public int a(int a, int b)
{
return a + b;
}
public int b(int a, int b)
{
return a - b;
}
}
class Program
{
static void Main(string[] args)
{
class2 c = new class2(); // 클래스 선언
dele call = new dele(c.a); // 델리게이트 선언
Console.WriteLine(call(3, 4));
call = new dele(c.b); // 델리게이트 다시 선언
Console.WriteLine(call(5, 2));
}
}
}
// 델리게이트를 선언하고 거기에 해당 클래스의 메소드를 넣어주고 접근하게함
// 델리게이트가 메소드들을 바꿔가며 연결해줌
// 그닥 필요없어보임
* 메소드<T>( ) where T : Icompareble<T> 의 사용법
- a.compareTo(b);
// 매개변수 b가 a보다 크면 -1, 같으면 0 작으면 1 반환
* 델리게이트 일반화
namespace DelegateChains
{
delegate T dele<T>(T a, T b);
class Program
{
static int a<T>(T x, T y)
{
Console.WriteLine("{0} {1}", x, y);
return 1;
}
static string b<T>(T x, T y)
{
Console.WriteLine("{0} {1}", x, y);
return "a";
}
static void ccc<T>(T a, T b, dele<T> call)
{
call(a, b);
}
static void Main(string[] args)
{
ccc(10, 20, new dele<int>(a));
ccc("a", "b", new dele<string>(b));
}
}
}
// 일반화는 메소드를 이용해야하기 때문에 한계가 많다.
// 델리게이트를 파라미터로 선언해줌
// 불러올 메소드와 그 자료형을 함께 넘겨준다.
* 델리게이트 체인
delegate void dele(string abc);
class noti
{
public dele even;
}
class bbb
{
public string name;
public bbb(string mess)
{
name = mess;
}
public void ccc(string mess)
{
Console.WriteLine("{0} {1}", name, mess);
}
}
class Program
{
static void Main(string[] args)
{
noti noti = new noti();
bbb a = new bbb("a"); // 클래스를 3개 선언함
bbb b = new bbb("b");
bbb c = new bbb("c");
// 첫번째 방법
noti.even += a.ccc; // 기존형과 다른 dele even = 함수;
noti.even += b.ccc;
noti.even += c.ccc;
noti.even("aaaa");
noti.even -= a.ccc;
noti.even("bbbb");
// 두번째 방법
noti.even = new dele(a.ccc) + new dele(b.ccc); // 기존형과 동일한 dele even = new dele(함수) 형태
noti.even("cccc");
noti.even -= new dele(a.ccc);
noti.even("dddd");
}
}
// 델리게이트는 체인으로 추가와 삭제가 가능하고 한번에 여러 메소드를 한 번에 출력할 수 있다.
* 익명 메소드
delegate int dele(int a, int b);
class Program
{
static void Main(string[] args)
{
dele call = delegate (int a, int b)
{
return a + b;
};
Console.WriteLine(call(3, 6));
Console.WriteLine(call(5, 2));
}
}
// 아주 간단해졌다.
// 델리게이트에 메소드를 넣고 다시 델리게이트에서 메소드로 접근하지 않음
// 아예 델리게이트에 메소드를 써줘버림.. 다음부턴 델리게이트에서 가져오는건 그 메소드이다.
* 이벤트
delegate void EventHandler(string message); // 델리게이트 선언
class MyNotifier
{
public event EventHandler SomethingHappened; // 델리게이트 인스턴스를 이벤트로 선언
public void DoSomething(int number)
{
int temp = number % 10;
if ( temp != 0 && temp % 3 == 0)
{
SomethingHappened(String.Format("{0} : 짝", number)); // 이벤트(값)
}
}
}
class MainApp
{
static public void MyHandler(string message) // 이벤트 핸들러. 델리게이트와 반환형, 파라미터 일치함
{
Console.WriteLine(message);
}
static void Main(string[] args)
{
MyNotifier notifier = new MyNotifier(); // 이벤트가 들어있는 클래스 선언
notifier.SomethingHappened += new EventHandler(MyHandler); // 이벤트 += 델리게이트(핸들러)
// notifier.DoSomething(6); 직접 외부에서 호출 안됨
for (int i = 1; i < 30; i++)
{
notifier.DoSomething(i); // 클래스.메소드(값)
}
}
}
// 이벤트와 델리게이트가 하는 일은 결국 메소드를 사용하겠다는 것이다.
// 이벤트와 델리게이트의 가장 큰 차이점은 이벤트는 외부에서 호출할 수 없다는 것이다.
// 이벤트 있는 클래스 선언 -> 이벤트 += 델리(핸들러) -> 클래스.메소드() -> 이벤트() -> 핸들러 출력
// 결론은 이벤트에 도달하면 핸들러로 이동해서 출력하겠다는건데 엄청 복잡하게 하고 있다.