C# 入門

ホーム > デリゲート > デリゲートの基本

デリゲートの基本

デリゲート (delegate) は C 言語などでいうところの関数ポインタのようなものです。

関数ポインタを型として定義しておき、実行時に関数への参照をセットします。関数への参照を使って元の関数を呼び出すということができます。

デリゲートも関数ポインタと同様で、「こんな形(戻り値とパラメータ)のメソッドを呼び出します」ということだけ定義しておき、 メソッドの実体を実行時にセットすることができます。

どうしてこんなことをするかというと、例えばイベント処理を考えると分かりやすいでしょう。

ボタンのクリックイベントを定義したいとします。クリックイベントでは

「ボタンをクリックしたら、こんなパラメータのこんなメソッドを呼びだす」

というように定義したいですよね。 特定の唯一のメソッドしか呼び出せなかったら、そのボタンはあなたのプログラム固有の動作をすることができないので使い物にならないですよね?

ま、イベントについては実はもうちょっと別の問題が出てくるのでここでは深追いしません。イベントについては別の記事に書きます。

要は「こんな型のメソッドを呼び出したい」ということだけ定義しておいて、後でそのメソッドの実体をセットしたほうが都合が良い場合がある、ということです。

デリゲートの例

ではさっそく、デリゲートの利用例をみてみましょう。次のようにします。

using System;

namespace DelegateTest1
{
	class Class1
	{
		public delegate void f1Delegate();
		public f1Delegate f1;

		public void Test()
		{
			if (f1 != null)
			{
				f1();
			}
		}
	}
}

という Class1 を作り、次のように使います。

using System;

namespace DelegateTest1
{
	class Program
	{
		static void Main(string[] args)
		{
			Class1 c1 = new Class1();
			c1.f1 = new Class1.f1Delegate(a);
			c1.Test();
		}

		static void a()
		{
			Console.WriteLine("I'm a().");
		}
	}
}

実行結果は次の通り。確かに a() が呼ばれています。

I'm a().

さて、これはいったいどういうことでしょうか。 もう一度 Class1 に戻ってみていきましょう。

delegate キーワードの行は次のようになります。

		public delegate void f1Delegate();

これは「戻り値無し (void)」 かつ「引数無し」のデリゲート型を定義しています。

		public f1Delegate f1;

という行で、「『戻り値無し』かつ『引数無し』のデリゲート型の変数 f1」を定義しています。 つまり f1 というのは『戻り値無し』かつ『引数無し』のメソッドへの参照ということができます。

f1 は型は定義されてはいますが、ここではそのメソッドの実体はセットされていません。 これは後で必要に応じてセットします。

Test メソッドでは、f1 にメソッドの実体がセットされていれば (f1 が null でなければ) それを呼び出します。

		public void Test()
		{
			if (f1 != null)
			{
				f1();
			}
		}

さて、こうして定義した Class1 の利用側は次の通り。

			Class1 c1 = new Class1();

として Class1 のインスタンスをつくり・・・

			c1.f1 = new Class1.f1Delegate(a);

ここでデリゲート型のインスタンスを作り、それを f1 にセットしています。インスタンスを作るときに、 デリゲートで定義したメソッドと同じ型のメソッド (ここでは a()) を渡しています。

これで f1 がメソッド a をポイントするようになります。

この結果、Test メソッドで f1 を呼び出したときに a が呼び出されることになります。

ホーム > デリゲート > デリゲートの基本