デリゲート (Visual Basic)Delegates (Visual Basic)

デリゲートは、メソッドを参照するオブジェクトです。Delegates are objects that refer to methods. デリゲートは他のプログラミング言語で使用される関数ポインターに似ているため、"タイプ セーフ関数ポインター" と説明されることがあります。They are sometimes described as type-safe function pointers because they are similar to function pointers used in other programming languages. Visual Basic のデリゲートでは、関数ポインターとは異なり、クラスに基づく参照型が、System.Delegateします。But unlike function pointers, Visual Basic delegates are a reference type based on the class System.Delegate. デリゲートは、共有メソッド (特定のクラスのインスタンスがなくても呼び出すことのできるメソッド) とインスタンス メソッドの両方を参照できます。Delegates can reference both shared methods — methods that can be called without a specific instance of a class — and instance methods.

デリゲートとイベントDelegates and Events

デリゲートは、呼び出し側プロシージャと呼び出されるプロシージャの間の媒介手段が必要な状況で役立ちます。Delegates are useful in situations where you need an intermediary between a calling procedure and the procedure being called. たとえば、イベントを発生させるオブジェクトが、異なる状況で別個のイベント ハンドラーを呼び出せるようにする必要がある場合があります。For example, you might want an object that raises events to be able to call different event handlers under different circumstances. しかし、イベントを発生させるオブジェクトは、どのイベント ハンドラーが特定のイベントを処理するかをあらかじめ把握できません。Unfortunately, the object raising the events cannot know ahead of time which event handler is handling a specific event. Visual Basic を使用するイベント ハンドラーを動的に関連付けるイベントを使用する場合、デリゲートを作成して、AddHandlerステートメント。Visual Basic lets you dynamically associate event handlers with events by creating a delegate for you when you use the AddHandler statement. 実行時に、デリゲートによって適切なイベント ハンドラーに呼び出しが転送されます。At run time, the delegate forwards calls to the appropriate event handler.

Visual Basic のデリゲートを作成し、詳細が処理のほとんどの場合は、独自のデリゲートを作成できます。Although you can create your own delegates, in most cases Visual Basic creates the delegate and takes care of the details for you. たとえば、Event ステートメントは、Event ステートメントを含むクラスの入れ子のクラスとして、<EventName>EventHandler という名前のデリゲート クラスをイベントと同じシグネチャを使用して暗黙的に定義します。For example, an Event statement implicitly defines a delegate class named <EventName>EventHandler as a nested class of the class containing the Event statement, and with the same signature as the event. AddressOf ステートメントは、特定のプロシージャを参照するデリゲートのインスタンスを暗黙的に作成します。The AddressOf statement implicitly creates an instance of a delegate that refers to a specific procedure. 次の 2 つのコード行は同等です。The following two lines of code are equivalent. 最初の行では、EventHandler のインスタンスが明示的に作成され、メソッド Button1_Click への参照が引数として渡されます。In the first line, you see the explicit creation of an instance of EventHandler, with a reference to method Button1_Click sent as the argument. 2 番目の行は、より便利な方法で同じことを実行します。The second line is a more convenient way to do the same thing.

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

コンパイラがデリゲートの種類をコンテキストから判断できる場合は、デリゲートの簡単な作成方法を使用できます。You can use the shorthand way of creating delegates anywhere the compiler can determine the delegate's type by the context.

既存の種類のデリゲートを使用するイベントの宣言Declaring Events that Use an Existing Delegate Type

状況によっては、基になるデリゲートとして既存のデリゲートを使用するイベントを宣言する必要が生じることがあります。In some situations, you may want to declare an event to use an existing delegate type as its underlying delegate. その方法を次の構文に示します。The following syntax demonstrates how:

Delegate Sub DelegateType()
Event AnEvent As DelegateType

これは、同じハンドラーに複数のイベントをルーティングする場合に役立ちます。This is useful when you want to route multiple events to the same handler.

デリゲート変数とパラメーターDelegate Variables and Parameters

デリゲートは、フリースレッド処理や、実行時に異なるバージョンの関数を呼び出す必要があるプロシージャなど、イベントに関連しない他のタスクにも使用できます。You can use delegates for other, non-event related tasks, such as free threading or with procedures that need to call different versions of functions at run time.

たとえば、自動車の名前のリスト ボックスを含む、項目別広告のアプリケーションがあるとします。For example, suppose you have a classified-ad application that includes a list box with the names of cars. 広告はタイトル(通常は自動車の型式) で並べ替えられます。The ads are sorted by title, which is normally the make of the car. 問題が発生する可能性があるのは、型式の前に年式が含まれている自動車があるときです。A problem you may face occurs when some cars include the year of the car before the make. 問題になるのは、リスト ボックスに組み込まれた並べ替え機能の並べ替えの基準が文字コードだけであることです。このため、日付で始まるすべての広告が最初に配置され、その後に型式で始まる広告が配置されます。The problem is that the built-in sort functionality of the list box sorts only by character codes; it places all the ads starting with dates first, followed by the ads starting with the make.

この問題を解決するために、クラスに並べ替えプロシージャを作成できます。このプロシージャは、ほとんどのリスト ボックスに対応する標準的なアルファベット順の並べ替えを使用しますが、実行時に自動車広告用のカスタム並べ替えプロシージャに切り替えることができます。To fix this, you can create a sort procedure in a class that uses the standard alphabetic sort on most list boxes, but is able to switch at run time to the custom sort procedure for car ads. このプロシージャを作成するには、デリゲートを使用して実行時にカスタム並べ替えプロシージャを並べ替えクラスに渡します。To do this, you pass the custom sort procedure to the sort class at run time, using delegates.

AddressOf とラムダ式AddressOf and Lambda Expressions

各デリゲート クラスでは、オブジェクト メソッドの仕様を渡すコンストラクターを定義します。Each delegate class defines a constructor that is passed the specification of an object method. デリゲート コンス トラクターに渡す引数は、メソッドへの参照、またはラムダ式である必要があります。An argument to a delegate constructor must be a reference to a method, or a lambda expression.

メソッドへの参照を指定するには、次の構文を使用します。To specify a reference to a method, use the following syntax:

AddressOf [expression.]methodNameAddressOf [expression.]methodName

コンパイル時の expression の型は、シグネチャがデリゲート クラスのシグネチャと同じで、指定された名前のメソッドを持つクラスまたはインターフェイスである必要があります。The compile-time type of the expression must be the name of a class or an interface that contains a method of the specified name whose signature matches the signature of the delegate class. methodName は、共有メソッドまたはインスタンス メソッドのいずれかにできます。The methodName can be either a shared method or an instance method. クラスの既定メソッドに対してデリゲートを作成する場合も、methodName は省略できません。The methodName is not optional, even if you create a delegate for the default method of the class.

ラムダ式を指定するには、次の構文を使用します。To specify a lambda expression, use the following syntax:

Function ([parm As type, parm2 As type2, ...]) expressionFunction ([parm As type, parm2 As type2, ...]) expression

次の例では、デリゲートの参照を指定するために使用される AddressOf 式とラムダ式を示します。The following example shows both AddressOf and lambda expressions used to specify the reference for a delegate.

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

関数のシグネチャは、デリゲート型のシグネチャと一致している必要があります。The signature of the function must match that of the delegate type. ラムダ式について詳しくは、「ラムダ式」をご覧ください。For more information about lambda expressions, see Lambda Expressions. ラムダ式のその他の例と AddressOf のデリゲートへの代入については、「厳密でないデリゲート変換」を参照してください。For more examples of lambda expression and AddressOf assignments to delegates, see Relaxed Delegate Conversion.

タイトルTitle 説明Description
方法: デリゲート メソッドを呼び出すHow to: Invoke a Delegate Method メソッドをデリゲートに関連付け、デリゲートからそのメソッドを呼び出す方法の例を示します。Provides an example that shows how to associate a method with a delegate and then invoke that method through the delegate.
方法: Visual Basic での別のプロシージャに渡すHow to: Pass Procedures to Another Procedure in Visual Basic デリゲートを使用してプロシージャを別のプロシージャに渡す方法を示します。Demonstrates how to use delegates to pass one procedure to another procedure.
厳密でないデリゲート変換Relaxed Delegate Conversion シグネチャが同じでない場合でも Sub や関数をデリゲートやハンドラーに割り当てる方法を説明します。Describes how you can assign subs and functions to delegates or handlers even when their signatures are not identical
イベントEvents Visual Basic のデリゲートの概要について説明します。Provides an overview of events in Visual Basic.