Home Full Site
C# delegate 필드/ delegate 속성

C# delegate 1 에서 보듯이, delegate는 메서드의 파라미터로 전달될 수 있다. 이와 맥락을 같이하여 delegate는 또한 클래스의 필드나 속성에 사용될 수 있다. 일종의 함수 포인터를 필드나 속성에 저장 하는 것과 비슷한 맥락이다. 메서드 파라미터로 전달하던, 필드로 저장하던 클래스 객체의 입장에서는 전달된 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 클릭!";
      }
   }
}

  • 예제의 MyClick 필드는 area.MyClick = Area_Click; 문장이 실행되어 여기서는 하나의 메서드 레퍼런스만을 가진다. 만약 다른 메서드를 이 필드(혹은 속성)에 = 연산자를 써서 다시 할당하면, 필드에는 마지막 할당된 메서드만 저장된다.
  • C# delegate는 += Operator를 사용하면 복수 메서드들을 가질 수 있다


C# Multicast Delegate

C# delegate는 여러 개의 메서드들을 할당하는 것이 가능하다. C# 연산자 += 을 사용하면 메서드를 계속 delegate 에 추가하게 되는데, 내부적으로는 .NET MulticastDelegate 클래스에서 이 메서드들의 리스트(이를 InvocationList 라고 한다)를 관리하게 된다.

복수개의 메서드들이 한 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 클릭! ";
   }
}



© csharpstudy.com