대리자의 선언
public delegate int MyDelegate (int a, int b);
대리자의 사용
MyDelegate Callback;
int Plus( int a, int b)
{
return a+b;
}
int Minus ( int a, int b )
{
return a-b;
}
CallBack = new MyDelegate(Plus);
Console.WriteLine( CallBack(3,4) ); // 7 출력
CallBack = new MyDelegate(Minus);
Console.WriteLine( CallBack(7,5) ); // 2 출력
값이 아닌 코드를 매개변수에 넘기고 싶을 때 사용한다.
static void BubbleSort(int[] DataSet, Compare comparer) // Compare는 delegate
{
int i = 0;
int j = 0;
int temp = 0;
for( i=0; i<DataSet.Length-1; i++)
{
for(j=0; j<DataSet.Length - (i+1); j++)
{
if ( Comparer( DataSet[j] , DataSet[j+1] ) >0 )
{
temp = DataSet[j+1];
DataSet[j+1] = DataSet[j];
DataSet[j] = temp;
}
}
}
}
int [] array = {3,7,5,3,10};
BubbleSort(array,new Compare(AscendComparer)); // 매개인자에 메서드를 넣는 방법
선언
delegate int Compare<T>(T a, T b); // 선언
Static void BubbleSort<T>( T[] DataSet, Compare<T> comparer) // 사용
static int AscendCompare<T>(T a,T b) where T : IComparable<T>
대리자는 여러가지의 메서드를 체인형식으로 (순서대로) 추가, 참조할 수 있다.
delegate void ThereIsAFire(string location);
void Call119 (string location)
{
Console.WriteLine("소방서죠? 불났어요! 주소는 {0}",location);
}
ThereIsAFire Fire = new ThereIsFire ( Call119 );
Fire += new ThereIsAFire(ShotOut); // += 연산자로 추가 가능, -=을 이용하면 체인 끊기도 가능.
Fire += new ThereIsAFire(Escape);
Fire("우리집"); // 소방서죠? 불났어요 주소는 우리집, 피하세요! 우리집에 불이났어요 , 우리집에서 나갑시다! -> 함수가 연속적으로 추가한대로실행
이름이 없는 메소드이다. 대리자를 이용해 구현한다.
public static void Main()
{
Calculate Calc;
Calc = delegate ( int a, int b ) // 익명메소드는 delegate를 이용해 구현
{
return a+b;
};
Console.WriteLine("3+4 : {0}", Calc(3,4));
이벤트는 대리자를 event 한정자로 수식하여 만든다.
이벤트 선언 및 사용 절차
1) 대리자 선언, 클래스 밖 or 안 상관없음
delegate void EventHandler(string message);
2) 클래스 내에 선언한 대리자의 인스턴스를 event 한정자로 수식하여 선언
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));
}
}
}
3) 이벤트 핸들러를 착성한다. 이벤트 핸들러는 대리자와 형식이 일치하는 메소드면 된다.
class MainApp
{
static public void MyHandler (string message)
{
Console.WriteLine(message);
}
//.....
}
4) 클래스의 인스턴스를 생성하고 이 객체의 이벤트에 작성한 이벤트 핸들러를 등록한다.
대리자의 체인속성을 이용하여 추가할수 있음.
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 클래스에 있는 SomethingHappened 이벤트에 MyHandler 메소드를 이벤트로 등록
for (int i=1; i<30; i++)
{
notifier.DoSomething(i);
}
}
}
이벤트와 대리자의 가장 큰 차이점 : 이벤트는 외부에서 직접 사용할 수 없다.
이벤트는 public 으로 선언되어 있어도 자신이 선언된 클래스 외부에서는 호출이 불가능하다.
반면 대리자는 public이나 internal로 선언되어있으면 클래스 외부에서 호출가능하다.