連載

One Point .NET

デリゲート再入門

吉松 史彰
2003/07/23

 .NET Frameworkでは、イベント・ハンドラやコールバックの機能を「デリゲート」を用いて実現する。このため、「デリゲートはイベントを実現するため(だけ)に存在する仕組みである」とか、「デリゲートは関数ポインタと同義である」などの誤解が見られる。デリゲートは確かに理解しづらい機能であり、またオブジェクト指向プログラミングにそぐわない機能でもあるかもしれない。だが、いずれにしろデリゲートはC#やVisual Basic .NET(以下VB.NET)などの言語でサポートされており、これらの言語を使用してアプリケーションを構築する際には押さえておかなければならない重要なポイントである。ここではいま一度、デリゲートを利用したプログラミング方法やデリゲートがもたらす機能についてまとめてみる。

通常のメソッド呼び出し

 .NET Frameworkにおいては、ある機能を実行するにはメソッドを呼び出す必要がある。また、ほとんどのプログラミング環境において、メソッドや関数の呼び出しと、呼び出されるメソッドや関数の実装とは、コンパイル時に対応付けられる(仮想メソッド・ディスパッチとの関連については後述)。例えば次のようなメソッドの呼び出しを考えてみる。

MessageBox.Show("hello, world.");

 MessageBoxクラスのShowメソッドと、それを呼び出しているこのコードは、コンパイル時に結び付けられる。

メソッドとそのメソッドの呼び出しはコンパイル時に結び付けられる

 しかし、メソッドの呼び出しと呼び出されるメソッドをコンパイル時に結び付けることはできない場合もある。例えばWindowsフォーム上に配置したButtonコントロールを考えてみよう。Visual Studio .NETでWindowsアプリケーションのプロジェクトを作成し、フォームにButtonコントロールをドロップして、ダブルクリックすると、ソースコード・エディタが表示される。そこでbutton1_Clickメソッドにコードを記述しておくと、作成されたWindowsアプリケーションを実行してボタンをクリックしたときに、button1_Clickメソッドが呼び出されてその中のコードが実行される。

フォームにButtonコントロールをドロップする

Buttonコントロールをダブルクリックして、button1_Clickメソッドにコードを記述する

アプリケーションを実行してボタンをクリックすると、button1_Clickメソッドが呼び出される

 つまり、実行時にButtonコントロールが画面上でクリックされると、Buttonコントロールがそれを認識し、Buttonコントロールを実装しているクラス・ライブラリ中のコードがbutton1_Clickメソッドを呼び出して、button1_Clickメソッドで記述した機能が実行されていることになる。

 だが、実際にはそのようなことは実現できない。ButtonコントロールはMicrosoftの開発者が開発したコードで成り立っているが、Microsoftの開発者がButtonコントロールを開発した時点では、まだbutton1_Clickメソッドは存在していない。存在しないメソッドを呼び出すコードなど書きようがない。Buttonコントロールを実装しているコードと、そこから呼び出されるbutton1_Clickメソッドとを、Buttonコントロールのコンパイル時に結び付けることはできないのである。

呼び出しと呼び出されるコードの間のクッション

 デリゲートは、メソッドを呼び出すコードと、呼び出されるメソッドとを分離する機能を提供する、共通言語ランタイムの組み込み機能である。デリゲートを使うと、メソッド呼び出しは次の図のように間接的になる。

デリゲートを使用するとメソッドの呼び出しは間接的になる

 メソッドを呼び出す側は、メソッドを呼び出す代わりにデリゲートを呼び出す。そのため、メソッドを呼び出す側をコンパイルするときに必要な情報は、デリゲートだけになる。デリゲートの先にある実際に呼び出されるメソッドの情報を知っている必要はないのである。

 一方、呼び出される側のメソッドは、実行時にデリゲートに対して登録が行われる。メソッドの呼び出しと、それによって呼び出されるメソッドは、この時点で初めて結び付けられることになる。つまり、メソッドの呼び出しに反応して呼び出されるメソッドは、実行してみるまで分からないということになっている。このように中間的なオブジェクトを設けることでメソッドの呼び出しに柔軟性を提供するのが、デリゲートの目的である。


 INDEX
  連載 One Point .NET
  デリゲート再入門
  1.デリゲートの役割
    2.デリゲートの実体とその利用方法
    3.マルチキャストとメソッドの非同期実行
 
「連載 One Point .NET」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間