ジェネリックの仕組みは、デリゲートの宣言にも適用できます。そのようなデリゲートは「ジェネリック・デリゲート」と呼ばれます(デリゲートって何だっけ? という人は、次項の【コラム】をまずご覧ください)。
例えば、.NET Framework 2.0のクラス・ライブラリ(System名前空間)には、次のようなジェネリック・デリゲートの定義(宣言)が含まれています。
public delegate void Action<T>(T obj)
Public Delegate Sub Action(Of T)(obj As T)
これは「Action<T>デリゲート」(VBでは「Action(Of T)デリゲート」)と呼ばれます。このデリゲートは、パラメータを1つ取り、戻り値を持たないメソッドに対して汎用的に使用できるデリゲートです。
例えば、次のようなメソッドがあるとしましょう。
void StringAction(string s) {
Console.WriteLine(s);
}
Sub MyAction(ByVal s As String)
Console.WriteLine(s)
End Sub
このメソッドに対しては、次のように具体的な型(ここではstring型)を型パラメータに指定して、デリゲートのインスタンスを作成できます。
Action<string> myActionDelegate = new Action<string>(StringAction);
Dim myActionDelegate As Action(Of String) = AddressOf MyAction
ちなみに、VBでは次のようにも記述できます(デリゲートのコンストラクタを明示的に呼び出す書き方です)。
Dim myActionDelegate As New Action(Of String)(AddressOf MyAction)
C#の場合にも、もっと省略した記述方法がありますが、それについては後述しています。
【コラム】 デリゲートの復習
デリゲートとはメソッドを間接的に呼び出すためのものです。デリゲートの機能により「メソッドへのポインタ」を表すオブジェクトを作成することができます。デリゲートの宣言は、そのようなオブジェクトの「型」を定義しているといえます。
いま、1つのstring型のパラメータを取り、戻り値としてstring型を返すようなメソッド「MyFunction」があるとしましょう。
このとき、次のようにして「MyFuncDelegate」という名前のデリゲートを宣言できます。
delegate string MyFuncDelegate(string s);
Delegate Function MyFuncDelegate(ByVal s As String) As String
次に、メソッド名をパラメータとして、デリゲートのインスタンス(=オブジェクト)を作成します。
MyFuncDelegate myfunc = new MyFuncDelegate(MyFunction);
Dim myfunc As MyFuncDelegate = AddressOf MyFunction
これで、MyFunctionメソッドを直接呼び出す代わりに、変数myfuncをメソッドのようにして呼び出すことができます。
string s = myfunc("Mike");
Dim s As String = myfunc("Mike")
myfuncオブジェクトは、MyFunctionメソッドへのポインタといえます。このオブジェクトをほかのメソッドに渡して、別のところからメソッドを呼び出してもらう(コールバックしてもらう)といったことができるようになります。
次のサンプル・プログラムは以上の内容をまとめたものです。
using System;
class DelegateSample
{
// デリゲートの宣言
delegate string MyFuncDelegate(string s);
string MyFunction(string s) {
return s + "サンこんにちは";
}
void CallDelegate(MyFuncDelegate f) {
string s = f("Mary");
Console.WriteLine(s);
}
void Sample() {
// デリゲート・インスタンスの作成
MyFuncDelegate myfunc = new MyFuncDelegate(MyFunction);
// デリゲート経由でメソッドを呼び出す
string s = myfunc("Mike");
Console.WriteLine(s);
// 出力:Mikeサンこんにちは
// デリゲートを渡してメソッドを呼び出してもらう
CallDelegate(myfunc);
// 出力:Maryサンこんにちは
}
static void Main() {
DelegateSample ds = new DelegateSample();
ds.Sample();
}
}
Imports System
Class DelegateSample
' デリゲートの宣言
Delegate Function MyFuncDelegate(ByVal s As String) As String
Function MyFunction(ByVal s As String) As String
Return s + "サンこんにちは"
End Function
Sub CallDelegate(ByVal f As MyFuncDelegate)
Dim s As String = f("Mary")
Console.WriteLine(s)
End Sub
Sub Sample()
' デリゲート・インスタンスの作成
Dim myfunc As MyFuncDelegate = AddressOf MyFunction
' デリゲート経由でメソッドを呼び出す
Dim s As String = myfunc("Mike")
Console.WriteLine(s)
' 出力:Mikeサンこんにちは
' デリゲートを渡してメソッドを呼び出してもらう
CallDelegate(myfunc)
' 出力:Maryサンこんにちは
End Sub
Shared Sub Main()
Dim ds As New DelegateSample()
ds.Sample()
End Sub
End Class
Copyright© Digital Advantage Corp. All Rights Reserved.