C# delegate 필드와 delegate 속성
C# delegate 1 에서 보듯이, delegate는 메서드의 파라미터로 전달될 수 있다. 이와 맥락을 같이하여 delegate는 또한 클래스의 필드나 속성에 사용될 수 있다. 일종의 함수 포인터를 필드나 속성에 저장 하는 것과 비슷한 맥락이다. 메서드 파라미터로 전달하던, 필드로 저장하던 클래스 객체의 입장에서는 전달된 delegate를 필요에 따라 자신의 클래스 내에서 사용하면 된다.
아래 예는 delegate 필드(MyClick)를 정의한 후, 클래스 내부 함수(MyAreaClicked)에서 delegate 필드가 NULL이 아니면, 해당 delegate를 실행하는( MyClick(this); ) 코드를 보여준다. delegate 실행은 메서드를 호출하는 것과 같은데, 델리게이트 필드 자신이 마치 메서드명인 것처럼 사용하면 된다.
아래 예는 delegate 필드(MyClick)를 정의한 후, 클래스 내부 함수(MyAreaClicked)에서 delegate 필드가 NULL이 아니면, 해당 delegate를 실행하는( MyClick(this); ) 코드를 보여준다. delegate 실행은 메서드를 호출하는 것과 같은데, 델리게이트 필드 자신이 마치 메서드명인 것처럼 사용하면 된다.
예제
using System.Windows.Forms;
namespace MySystem
{
class MyArea : Form
{
public MyArea()
{
// 이 부분은 당분간 무시 (무명메서드 참조)
// 예제를 테스트하기 위한 용도임.
this.MouseClick += delegate { MyAreaClicked(); };
}
public delegate void ClickDelegate(object sender);
// Delegate 필드
public ClickDelegate MyClick;
// 필드 대신 Delegate 속성으로도 가능
//public ClickDelegate Click { get; set; }
//...
//...
// 예제를 단순화 하기 위해
// MyArea가 클릭되면 아래 함수가 호출된다고 가정
void MyAreaClicked()
{
if (MyClick != null)
{
MyClick(this);
}
}
}
class Program
{
static MyArea area;
static void Main(string[] args)
{
area = new MyArea();
area.MyClick = Area_Click;
area.ShowDialog();
}
static void Area_Click(object sender)
{
area.Text = "MyArea 클릭!";
}
}
}
namespace MySystem
{
class MyArea : Form
{
public MyArea()
{
// 이 부분은 당분간 무시 (무명메서드 참조)
// 예제를 테스트하기 위한 용도임.
this.MouseClick += delegate { MyAreaClicked(); };
}
public delegate void ClickDelegate(object sender);
// Delegate 필드
public ClickDelegate MyClick;
// 필드 대신 Delegate 속성으로도 가능
//public ClickDelegate Click { get; set; }
//...
//...
// 예제를 단순화 하기 위해
// MyArea가 클릭되면 아래 함수가 호출된다고 가정
void MyAreaClicked()
{
if (MyClick != null)
{
MyClick(this);
}
}
}
class Program
{
static MyArea area;
static void Main(string[] args)
{
area = new MyArea();
area.MyClick = Area_Click;
area.ShowDialog();
}
static void Area_Click(object sender)
{
area.Text = "MyArea 클릭!";
}
}
}
- 예제의 MyClick 필드는 area.MyClick = Area_Click; 라는 할당 연산자 문장이 실행되어 하나의 메서드 레퍼런스만을 가진다. 만약 다른 메서드를 이 필드(혹은 속성)에 할당 연산자(=)를 써서 다시 할당하면, 필드에는 기존 메서드 정보는 지우고 가장 최근에 할당한 메서드만 저장하게 된다.
- C# delegate는 할당 연산자(=) 대신 += Operator를 사용하면 델리게이트 객체 내에 여러 메서드들에 대한 리스트 정보를 가지게 된다.
C# Multicast Delegate
C# delegate는 여러 개의 메서드들을 할당하는 것이 가능하다. C# 연산자 += 을 사용하면 메서드를 계속 delegate 에 추가하게 되는데, 내부적으로는 .NET MulticastDelegate 클래스에서 이 메서드들의 리스트(이를 InvocationList 라고 한다)를 관리하게 된다.
복수개의 메서드들이 한 delegate에 할당되면, 이 delegate가 실행될 때, InvocationList로부터 순서대로 메서드를 하나씩 가져와 실행한다. 아래 예제는 복수 개의 메서드를 한 delegate에 계속 추가하는 예이다.
복수개의 메서드들이 한 delegate에 할당되면, 이 delegate가 실행될 때, InvocationList로부터 순서대로 메서드를 하나씩 가져와 실행한다. 아래 예제는 복수 개의 메서드를 한 delegate에 계속 추가하는 예이다.
예제
class Program
{
static MyArea area;
static void Main(string[] args)
{
area = new MyArea();
//복수개의 메서드를 delegate에 할당
area.MyClick += Area_Click;
area.MyClick += AfterClick;
area.ShowDialog();
}
static void Area_Click(object sender)
{
area.Text += " MyArea 클릭! ";
}
static void AfterClick(object sender)
{
area.Text += " AfterClick 클릭! ";
}
}
{
static MyArea area;
static void Main(string[] args)
{
area = new MyArea();
//복수개의 메서드를 delegate에 할당
area.MyClick += Area_Click;
area.MyClick += AfterClick;
area.ShowDialog();
}
static void Area_Click(object sender)
{
area.Text += " MyArea 클릭! ";
}
static void AfterClick(object sender)
{
area.Text += " AfterClick 클릭! ";
}
}
C# 동영상 강의 : C# 델리게이트 (delegate) [레벨] 중급 [C# 중급] C# 델리게이트의 기초 개념과 C# 에서 delegate 를 정의하고 사용하는 방법에 대해 자세히 소개합니다. |