デリゲートは、メソッドを参照するオブジェクトです。 これらは、他のプログラミング言語で使用される関数ポインターに似ているため、 型セーフ な関数ポインターとして記述されることがあります。 ただし、関数ポインターとは異なり、Visual Basic デリゲートはクラス System.Delegateに基づく参照型です。 デリゲートは、共有メソッド (クラスの特定のインスタンスなしで呼び出すことができるメソッド) とインスタンス メソッドの両方を参照できます。
デリゲートとイベント
デリゲートは、呼び出し元のプロシージャと呼び出されるプロシージャの間に仲介者が必要な場合に便利です。 たとえば、イベントを発生させるオブジェクトが、さまざまな状況で異なるイベント ハンドラーを呼び出せるようにしたい場合があります。 残念ながら、イベントを発生させるオブジェクトは、特定のイベントを処理しているイベント ハンドラーを事前に認識できません。 Visual Basic では、 AddHandler
ステートメントを使用するときにデリゲートを作成することで、イベント ハンドラーをイベントに動的に関連付けることができます。 実行時に、デリゲートは適切なイベント ハンドラーに呼び出しを転送します。
独自のデリゲートを作成することはできますが、ほとんどの場合、Visual Basic によってデリゲートが作成され、詳細が自動的に処理されます。 たとえば、 Event
ステートメントは、 <EventName>EventHandler
という名前のデリゲート クラスを、 Event
ステートメントを含むクラスの入れ子になったクラスとして、イベントと同じシグネチャを持つデリゲート クラスを暗黙的に定義します。
AddressOf
ステートメントは、特定のプロシージャを参照するデリゲートのインスタンスを暗黙的に作成します。 次の 2 行のコードは同等です。 最初の行では、 EventHandler
のインスタンスが明示的に作成され、メソッドへの参照 Button1_Click
引数として送信されます。 2 行目は、同じことを行うためのより便利な方法です。
AddHandler Button1.Click, New EventHandler(AddressOf Button1_Click)
' The following line of code is shorthand for the previous line.
AddHandler Button1.Click, AddressOf Me.Button1_Click
コンパイラがコンテキストによってデリゲートの型を決定できる任意の場所でデリゲートを簡単に作成する方法を使用できます。
既存のデリゲート型を使用するイベントの宣言
場合によっては、既存のデリゲート型を基になるデリゲートとして使用するイベントを宣言することが必要な場合があります。 次の構文は、その方法を示しています。
Delegate Sub DelegateType()
Event AnEvent As DelegateType
これは、複数のイベントを同じハンドラーにルーティングする場合に便利です。
デリゲート変数とパラメーター
空きスレッド処理や、実行時に異なるバージョンの関数を呼び出す必要があるプロシージャなど、イベントに関連しないその他のタスクにデリゲートを使用できます。
たとえば、自動車の名前を含むリスト ボックスを含む、分類された広告アプリケーションがあるとします。 広告はタイトルで並べ替えられます。これは通常、自動車のメーカーです。 あなたが直面する可能性のある問題は、一部の車がメイク前の車の年を含むときに発生します。 問題は、リスト ボックスの組み込みの並べ替え機能が文字コードによってのみ並べ替えられるということです。日付から始まるすべての広告が最初に配置され、その後にメイクから始まる広告が表示されます。
これを解決するには、ほとんどのリスト ボックスで標準のアルファベット順の並べ替えを使用するクラスで並べ替えプロシージャを作成できますが、実行時に自動車広告のカスタム並べ替え手順に切り替えることができます。 これを行うには、デリゲートを使用して、実行時にカスタム並べ替えプロシージャを並べ替えクラスに渡します。
AddressOf およびラムダ式
各デリゲート クラスは、オブジェクト メソッドの仕様に渡されるコンストラクターを定義します。 デリゲート コンストラクターの引数は、メソッドまたはラムダ式への参照である必要があります。
メソッドへの参照を指定するには、次の構文を使用します。
AddressOf
[expression
.]methodName
expression
のコンパイル時の型は、デリゲート クラスのシグネチャと一致するシグネチャを持つ、指定した名前のメソッドを含むクラスまたはインターフェイスの名前である必要があります。
methodName
には、共有メソッドまたはインスタンス メソッドのいずれかを指定できます。 クラスの既定のメソッドのデリゲートを作成する場合でも、 methodName
は省略可能ではありません。
ラムダ式を指定するには、次の構文を使用します。
Function
([parm
As type
, parm2
As type2
, ...]) expression
次の例は、デリゲートの参照を指定するために使用される AddressOf
式とラムダ式の両方を示しています。
Module Module1
Sub Main()
' Create an instance of InOrderClass and assign values to the properties.
' InOrderClass method ShowInOrder displays the numbers in ascending
' or descending order, depending on the comparison method you specify.
Dim inOrder As New InOrderClass
inOrder.Num1 = 5
inOrder.Num2 = 4
' Use AddressOf to send a reference to the comparison function you want
' to use.
inOrder.ShowInOrder(AddressOf GreaterThan)
inOrder.ShowInOrder(AddressOf LessThan)
' Use lambda expressions to do the same thing.
inOrder.ShowInOrder(Function(m, n) m > n)
inOrder.ShowInOrder(Function(m, n) m < n)
End Sub
Function GreaterThan(ByVal num1 As Integer, ByVal num2 As Integer) As Boolean
Return num1 > num2
End Function
Function LessThan(ByVal num1 As Integer, ByVal num2 As Integer) As Boolean
Return num1 < num2
End Function
Class InOrderClass
' Define the delegate function for the comparisons.
Delegate Function CompareNumbers(ByVal num1 As Integer, ByVal num2 As Integer) As Boolean
' Display properties in ascending or descending order.
Sub ShowInOrder(ByVal compare As CompareNumbers)
If compare(_num1, _num2) Then
Console.WriteLine(_num1 & " " & _num2)
Else
Console.WriteLine(_num2 & " " & _num1)
End If
End Sub
Private _num1 As Integer
Property Num1() As Integer
Get
Return _num1
End Get
Set(ByVal value As Integer)
_num1 = value
End Set
End Property
Private _num2 As Integer
Property Num2() As Integer
Get
Return _num2
End Get
Set(ByVal value As Integer)
_num2 = value
End Set
End Property
End Class
End Module
関数のシグネチャは、デリゲート型のシグネチャと一致する必要があります。 ラムダ式について詳しくは、「ラムダ式」をご覧ください。 ラムダ式とデリゲートへの AddressOf
割り当てのその他の例については、「 緩やかなデリゲート変換」を参照してください。
関連トピック
タイトル | 説明 |
---|---|
方法: デリゲート メソッドを呼び出す | メソッドをデリゲートに関連付け、デリゲートを使用してそのメソッドを呼び出す方法を示す例を示します。 |
方法: Visual Basic でプロシージャを別のプロシージャに渡す | デリゲートを使用して、あるプロシージャを別のプロシージャに渡す方法を示します。 |
緩やかなデリゲート変換 | シグネチャが同一でない場合でも、デリゲートまたはハンドラーにサブと関数を割り当てる方法について説明します |
イベント | Visual Basic のイベントの概要について説明します。 |
.NET