대리자와 이벤트

최태선·2022년 3월 11일
0

이것이 C#이다

목록 보기
7/10

대리자

1. 대리자는 CallBack을 맡아 실행한다. 대리자는 메소드에대한 참조이고, 대리자를 호출하면 대리자가 메소드를 호출한다.

대리자의 선언

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 출력

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)); // 매개인자에 메서드를 넣는 방법

3. 일반화 대리자

선언

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>

4. 대리자 체인

대리자는 여러가지의 메서드를 체인형식으로 (순서대로) 추가, 참조할 수 있다.

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("우리집"); // 소방서죠? 불났어요 주소는 우리집,  피하세요! 우리집에 불이났어요 , 우리집에서 나갑시다! -> 함수가 연속적으로 추가한대로실행

5. 익명메소드

이름이 없는 메소드이다. 대리자를 이용해 구현한다.

public static void Main()
{
	Calculate Calc;
    Calc = delegate ( int a, int b ) // 익명메소드는 delegate를 이용해 구현
    {
    	return a+b;
    };
   
   Console.WriteLine("3+4 : {0}", Calc(3,4));

이벤트

6. 이벤트 : 객체에 일어난 사건 알리기

이벤트는 대리자를 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);
        }
    }
}

7. 대리자와 이벤트

이벤트와 대리자의 가장 큰 차이점 : 이벤트는 외부에서 직접 사용할 수 없다.
이벤트는 public 으로 선언되어 있어도 자신이 선언된 클래스 외부에서는 호출이 불가능하다.
반면 대리자는 public이나 internal로 선언되어있으면 클래스 외부에서 호출가능하다.

profile
최태선입니다

0개의 댓글