Delegáti (Visual Basic)

Delegáti jsou objekty, které odkazují na metody. Někdy se označují jako ukazatele na funkce bezpečné pro typ , protože jsou podobné ukazatelům funkcí používaným v jiných programovacích jazycích. Na rozdíl od ukazatelů na funkci jsou Visual Basic delegáti referenčním typem založeným na třídě System.Delegate. Delegáti mohou odkazovat na obě sdílené metody – metody, které lze volat bez konkrétní instance třídy – a metody instance.

Delegáti a události

Delegáti jsou užitečné v situacích, kdy potřebujete zprostředkující mezi volající procedurou a voláním procedury. Můžete například chtít, aby objekt, který vyvolává události, mohl za různých okolností volat různé obslužné rutiny událostí. Objekt, který vyvolává události, bohužel nemůže předem vědět, která obslužná rutina události zpracovává konkrétní událost. Visual Basic umožňuje dynamicky přidružit obslužné rutiny událostí k událostem vytvořením delegáta za vás při použití AddHandler příkazu. V době běhu delegát přesměruje volání příslušné obslužné rutině události.

I když můžete vytvořit vlastní delegáty, ve většině případů Visual Basic vytvoří delegáta a postará se o podrobnosti za vás. Například Event příkaz implicitně definuje delegovanou třídu pojmenovanou <EventName>EventHandler jako vnořenou třídu třídy obsahující Event příkaz a se stejným podpisem jako událost. Příkaz AddressOf implicitně vytvoří instanci delegáta, který odkazuje na konkrétní proceduru. Následující dva řádky kódu jsou ekvivalentní. Na prvním řádku uvidíte explicitní vytvoření instance EventHandlerinstance s odkazem na metodu Button1_Click poslanou jako argument. Druhá čára je pohodlnější způsob, jak to samé udělat.

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

Můžete použít krátký způsob vytváření delegátů kdekoli, kde kompilátor může určit typ delegáta podle kontextu.

Deklarace událostí, které používají existující typ delegáta

V některých situacích můžete chtít deklarovat událost pro použití existujícího typu delegáta jako jeho podkladového delegáta. Následující syntaxe ukazuje, jak:

Delegate Sub DelegateType()
Event AnEvent As DelegateType

To je užitečné, když chcete směrovat více událostí do stejné obslužné rutiny.

Delegování proměnných a parametrů

Delegáty můžete použít pro jiné úlohy, které nesouvisely s událostmi, jako je bezplatné vlákno nebo postupy, které potřebují volat různé verze funkcí za běhu.

Předpokládejme například, že máte klasifikovanou aplikaci reklamy, která obsahuje seznam se jmény aut. Reklamy jsou seřazené podle názvu, což je obvykle název auta. K problému může dojít, když některé auta zahrnují rok auta před provedením. Problém spočívá v tom, že integrovaná funkce řazení seznamu seřadí pouze podle kódů znaků; umístí všechny reklamy začínající daty jako první, následované reklamami začínajícími na make.

Chcete-li tento problém vyřešit, můžete vytvořit postup řazení ve třídě, která používá standardní abecední řazení u většiny seznamů, ale je schopen přepnout za běhu na vlastní postup řazení pro reklamy na auta. Uděláte to tak, že předáte vlastní postup řazení třídě za běhu pomocí delegátů.

Výrazy AddressOf a Lambda

Každá třída delegáta definuje konstruktor, který je předán specifikaci metody objektu. Argument konstruktoru delegáta musí být odkaz na metodu nebo výraz lambda.

Pokud chcete zadat odkaz na metodu, použijte následující syntaxi:

AddressOf [expression.]methodName

Typ expression kompilace musí být název třídy nebo rozhraní, které obsahuje metodu zadaného názvu, jehož podpis odpovídá podpisu třídy delegáta. Může methodName se jednat o sdílenou metodu nebo metodu instance. Není methodName nepovinný, ani když vytvoříte delegáta pro výchozí metodu třídy.

Pokud chcete zadat výraz lambda, použijte následující syntaxi:

Function([parm As , As type2type, parm2 ...])expression

Následující příklad ukazuje výrazy AddressOf lambda použité k určení odkazu pro delegáta.

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

Podpis funkce se musí shodovat s typem delegáta. Další informace o výrazech lambda najdete v tématu Výrazy lambda. Další příklady výrazů lambda a AddressOf přiřazení delegátům naleznete v tématu Uvolněný převod delegáta.

Nadpis Popis
Postupy: Volání metody delegáta Poskytuje příklad, který ukazuje, jak přidružit metodu k delegátu a pak vyvolat danou metodu prostřednictvím delegáta.
Postupy: Předání procedur jiné proceduře v jazyce Visual Basic Demonstruje použití delegátů k předání jedné procedury do jiné procedury.
Volný převod delegáta Popisuje, jak můžete delegátům nebo obslužným rutinám přiřadit dílčí funkce, i když jejich podpisy nejsou identické.
Události Poskytuje přehled událostí v Visual Basic.