Top > .NET & Control > C# デリゲートとイベント(delegate と event)

デリゲートとイベント(delegate と event)

関数へのポインタ~デリゲート(Delegate)~

同じ型で引数なしのメソッド(関数)が100個以上あるプログラムがあります。UIはどんな方法でもいいのですが、プログラムリストから選択された「プログラム(メソッド:関数)」を呼ぶ出す方法を考えてみましょう。

その方法は、2種類。

一つは、プログラムリストから選択されたプログラムを、直接呼び出す方法です。

  if (ProgramSelectID == 0) Function0();
  else if (ProgramSelectID == 1) Function1();
  else if (ProgramSelectID == 2) Function2();

あるいは

  Switch(ProgramSelectID)
  {
   case 0: Function0(); break;
   case 1: Function1(); break;
   case 2: Function2(); break;
  }

もう一つは、メソッド(関数)へのポインタを使って、間接的に呼び出す用法です。この概念は、C言語でも導入されていました。

WindowsアプリケーションのGUIのOSとのメッセージの受取は、delegateを使っていますし、メッセージをアプリケーション側のクラスへの通知はイベントで行われます。

デリゲートとイベントの関係

別件で調べていて、こんなページを見つけました。
http://csharper.blog57.fc2.com/?tag=VB&vcr=b898ca744ac0638c4c1fff814f98798d

「シンタックスシュガー」って言葉知らなかった。
http://ja.wikipedia.org/wiki/%E7%B3%96%E8%A1%A3%E6%A7%8B%E6%96%87 Wikipediaにありました。糖衣構文=扱いが楽。なるほど。

C#では、一般的にデリゲートとイベントの結びつきは次の様に記述します。

 public delegate void SelDelegateList();

 public event SelDelegateList SelectMethod;

コード上、eventは1行で完結していますが、コンパイル結果は以下の様になります。(下記のように記述することも可能です)

 private SelDelegateList _event1;

 public event SelDelegateList SelectMethod
 {
  add { this._event1 += value; }
  remove { this._event1 -= value; }
 }

何故イベントハンドラに、追加したり削除できるのか、ピンとこなかった人もこれで納得できますよね。

そもそも、eventとは何か?

「一つのdelegateを管理するのがevent」

 イベントハンドラのadd、remove機能 と複数のイベントハンドラに対する一括呼び出し機能です(なお、一括といっても同時ではありません)。

1:1に対応した呼び出しは、eventでは行えない
 ということになります。

では、delegateを使ってどうにかしなければいけない。

答えは

delegateを宣言し、delegateの配列で行う。と考え実験したので、そのコードを見てみましょう。

実験コード

public delegate void SelectAlgorithmDelegate();

public partial class Form1 : Form
{
 SelectAlgorithmDelegate[] SelDelegateList =
  new SelectAlgorithmDelegate[100];

 public Form1()
 {
  InitializeComponent();

  // デリゲートの配列を定義(実際は、メンバー変数として定義する)
  // すべてのメソッドをDelegateオブジェクトに登録する
  SelDelegateList[0] = new SelectAlgorithmDelegate(Algorithm1_1);
  SelDelegateList[1] = new SelectAlgorithmDelegate(Algorithm1_2);
  ・・・・

  // Delegateオブジェクトの呼び出し
  //(実際は、選択された時に呼び出されるメソッドに記述)
  SelDelegateList[0]();
  SelDelegateList[1]();
 }

 private void Algorithm1_1()
 {
 }

 private void Algorithm1_2()
 {
 }
}

▲ページトップに戻る