C# delegate 예제를 보면 예제의 delegate 들은 모두 이미 정의된 메서드를 가리키고 있었다 이렇게 미리 정의된 메서드 들 과 달리 C# 2.0에서 부 터 메서드를 미리 정의하지 않아도 되는 메서드 명이 없는 무명 메서드를 지원 하게 되었다 만약 어떤 메서드 가 일회용으로 단순한 문장들로 구성 되어 있다면 굳이 별도의 메서드를 정의 하지 않아도 되는 것이다 무명 메서드를 만들기 위해서는 delegate 키워드와 함께 아래 파라미터와 실행 문장 블럭을 적으면 된다 delegate 뒤에 파라미터는 해당 메서드 원형(Prototype)에 맞는 동일한 파라미터 타입이여야 하며 실행 문장 블럭에는 여러 문장들을 쓸 수 있다 무명 메서드는 외관 상 인라인 메서드(Inline method) 형식을 띠며 무명 메서드 자체를 delegate 타입의 변수에 할당 할 수도 있다
// 무명 메서드 형식 : delegate(파라미터들){실행 문장들};
delegate(int param1){ Console.Write(param1); };
// 무명 메서드를 delegate 타입 변수에 할당
delegate void MyDelegate(int a);
MyDelegate d = delegate(int P)
{
Console.Wite(p);
};
d(100);
무명 메서드 사용
C# 무명 메서드를 사용 하기 위해서는 메서드가 필요한 곳에 직접 delegate 로 시작하는 무명 메서드를 써주면 된다 예를 들어 무명 메서드를 델리게이트 변수에 할당해서 사용할 수도 있고 메서드의 파라미터에 인 라인 형식으로 무명 메서드를 사용할 수도 있으며 또한 이벤트 핸들러를 추가하는 곳에서 무명 메서드를 사용할 수 있다
아래 예제는 이벤트 핸들러에 무명 메서드를 사용한 예이다 예제에서 button1.Click 에는 미리 정의된 메서드명 (button1_Click)을 가르키는 이벤트 핸들러를 지정하였고 button2.Click 에서는 무명 메서드를 사용하여 직접 간단한 문장을 인라인으로 delegate(){…} 안에 포함 시킨 것 이다
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// 메서드 명을 지정
this.button1.Click += new System.EventHandler(this.button1_Click);
// 무명 메서드를 지정
this.button2.Click += delegate(object s, EventArgs e)
{
MessageBox.Show("버튼2 클릭");
};
}
private void button1_Click(object sender, EventArgs e)
{
MessgeBox.Show("버튼 1 클릭");
}
}
델리게이트 타입 vs 무명 메서드
C#의 delegate 키워드는 델리 게이트 타입을 정의할 때도 사용 되고 무명 메서드를 정의할 때도 사용 된다 델리 게이트 타입을 정의 하는 아래 첫번째 예의 경우 SumDelegate는 Delegaet 클래스 타입명을 가르키게 되고 클래스 객체를 생성할 때와 같이 new 를 사용 하여 Delegate 객체를 생성하고 이 객체에 특정 메서드를 연관시켜 할당하게 된다.
무명 메서드는 이름이 없는 메서드 자체 만을 가르키는 것으로 그 자체로 Delegate 타입이 되는 것은 아니다 따라서 아래 [무명메서드1] 예제처럼 EventHandler 델리게이트 객체를 new 로 생성하고 무명메서드를 파라미터로 전달하게 된다 하지만 Event와 같이 이미 어떤 델리게이트 타입이 사용될 지 아는 경우에는 (컴파일러가 Click 이벤트는 new EventHandler(object, EventArgs) 형식의 이벤트 핸들러를 받아들인다는 것을 이미 알고 있다) 아래 [무명메서드 2/3] 예제처럼 new EventHandler()나 (EventHandler 캐스팅을 생략 할 수 있다 또한 마지막으로 만약 파라미터를 무명 메서드 안에서 사용하지 않는다면 [무명메서드4] 예제처럼 파라미터들을 완전히 생략할 수 도 있다
//Delegate 타입:
public delegate int SumDelegate(int a, int b);
// Delegate 사용:
SumDelegate sumDel = new SumDelegate(mySum);
// 무명메서드1
button1.Click += new EventHandler(delegate(object s, EventArgs a) { MessageBox.Show("OK"); });
// 무명메서드2
button1.Click += (EventHandler) delegate(object s,EventArgs a) { MessageBox.Show("ok");};
// 무명메서드3
button1.Click += delegate(object s, EventArgs a) {Message.Box("ok");};
// 무명메서드4
button.Click += delegate {MessgeBox.Show("ok");};
델리게이트 타입 vs 무명메서드
델리게이트 타입을 사용해야 하는 곳에 무명 메서드만 직접 사용 하는 경우 컴파일 에러 (Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type) 가 발생 할 수 있다
아래 예처럼 Control.Invoke() 혹은 Control.BeginInvoke() 메서드는 델리게이트 타입을 파라미터로 받아 들인다 즉 Invoke() 메서드는 파라미터로 받아들이는 Delegate의 파라미터가 몇 개인지 리턴 값은 무엇인지 미리 알지 못한다는 뜻이다 따라서 무조건 무명 메서드는 전달할 수 없고 어떤 Delegate 타입인지 명시적으로 지정해야 하고 이런 조건이 충족 되었을 때 Delegate 타입과 부합되는 무명 메서드를 사용 할 수 있다
// 틀림 : 컴파일 에러 발생
this.Invoke(delegate {button1.Text = s;} );
//맞는 표현
MethodInvoker mi = new MethodInvoker(delegate() { button1.Text = s; });
this.Invoke(mi);
// 축약된 표현
this.Invoke((MethodInvoker) delegate { button1.Text = s; });
/*
MethodInvoker는 입력 파라미터가 없고, 리턴 타입이 void인 델리게이트이다.
MethodInvoker는 System.Windows.Forms 에 다음과 같이 정의되어 있다.
public delegate void MethodInvoker();
*/
'개인 스터디' 카테고리의 다른 글
스핀락 (0) | 2024.10.16 |
---|---|
C# Thread(스레드) 주요 속성과 메서드 (0) | 2024.10.15 |
TCP 서버 (0) | 2024.10.11 |
TCP 클라이언트 (0) | 2024.10.11 |
Win Sock 과 .NET 클래스 (1) | 2024.10.11 |