Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Delegaty to obiekty odwołujące się do metod. Są one czasami opisywane jako wskaźniki funkcji bezpiecznego typu , ponieważ są one podobne do wskaźników funkcji używanych w innych językach programowania. Jednak w przeciwieństwie do wskaźników funkcji delegaty języka Visual Basic są typem referencyjnym opartym na klasie System.Delegate. Delegaty mogą odnosić się zarówno do metod statycznych — które mogą być wywoływane bez określonej instancji klasy — jak i metod instancyjnych.
Delegaty i zdarzenia
Delegaty są przydatne w sytuacjach, w których potrzebny jest pośrednik między procedurą wywołującą a procedurą, która jest wywoływana. Na przykład możesz chcieć, aby obiekt, który zgłasza zdarzenia, mógł wywoływać różne programy obsługi zdarzeń w różnych okolicznościach. Niestety obiekt podnoszący zdarzenia nie może wiedzieć wcześniej, który program obsługi zdarzeń obsługuje określone zdarzenie. Visual Basic umożliwia dynamiczne kojarzenie procedur obsługi zdarzeń ze zdarzeniami przez automatyczne utworzenie delegata dla Ciebie podczas korzystania z instrukcji AddHandler
. Podczas działania delegat przekazuje wywołania do odpowiedniego obsługiwacza zdarzeń.
Chociaż możesz utworzyć własnych delegatów, w większości przypadków program Visual Basic tworzy delegata i zajmuje się szczegółami. Na przykład instrukcja niejawnie definiuje klasę delegata Event
o nazwie <EventName>EventHandler
jako zagnieżdżoną klasę w klasie zawierającej tę instrukcję Event
i z taką samą sygnaturą co zdarzenie. Instrukcja AddressOf
niejawnie tworzy wystąpienie delegata, które odwołuje się do określonej procedury. Następujące dwa wiersze kodu są równoważne. W pierwszym wierszu zobaczysz jawne utworzenie wystąpienia klasy EventHandler
z odwołaniem do metody Button1_Click
wysłanej jako argument. Druga linia jest bardziej wygodnym sposobem, aby zrobić to samo.
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
Możesz użyć skróconego sposobu tworzenia delegatów w dowolnym miejscu, w którym kompilator może określić typ delegata według kontekstu.
Deklarowanie zdarzeń używających istniejącego typu delegata
W niektórych sytuacjach możesz zadeklarować zdarzenie, aby użyć istniejącego typu delegata jako delegata bazowego. Poniższa składnia pokazuje, jak:
Delegate Sub DelegateType()
Event AnEvent As DelegateType
Jest to przydatne, gdy chcesz kierować wiele zdarzeń do tego samego elementu obsługującego.
Delegowanie zmiennych i parametrów
Można używać delegatów dla innych, niezwiązanych z zdarzeniami zadań, takich jak wolne wątkowanie lub procedury, które muszą wywoływać różne wersje funkcji w czasie wykonywania.
Załóżmy, że masz na przykład aplikację z ogłoszeniami drobnymi, która zawiera listę z nazwami samochodów. Reklamy są sortowane według nazwy, która jest zwykle nazwą producenta samochodu. Problem może wystąpić, gdy niektóre samochody zawierają rok produkcji przed marką. Problem polega na tym, że wbudowana funkcja sortowania pola listy sortuje tylko według kodów znaków; umieszcza najpierw wszystkie reklamy rozpoczynające się od dat, a następnie reklamy zaczynające się od make.
Aby rozwiązać ten problem, można utworzyć procedurę sortowania w klasie, która używa standardowego sortowania alfabetycznego w większości pól listy, ale jest w stanie przełączyć się w czasie wykonywania do niestandardowej procedury sortowania reklam samochodowych. W tym celu należy przekazać niestandardową procedurę sortowania do klasy sortowania podczas wykonywania programu przy użyciu delegatów.
Wyrażenia AddressOf i wyrażenia Lambda
Każda klasa delegata definiuje konstruktor, który otrzymuje specyfikację metody obiektu. Argument konstruktora delegata musi być odwołaniem do metody lub wyrażenia lambda.
Aby określić odwołanie do metody, użyj następującej składni:
AddressOf
[expression
.]methodName
Typ expression
w czasie kompilacji musi być nazwą klasy lub interfejsu, który zawiera metodę o określonej nazwie, której sygnatura dokładnie odpowiada sygnaturze klasy delegującej.
methodName
może być albo metodą współdzieloną, albo instancyjną. Element methodName
nie jest opcjonalny, nawet jeśli utworzysz delegata dla domyślnej metody klasy.
Aby określić wyrażenie lambda, użyj następującej składni:
Function
([parm
Jako type
, parm2
jako type2
, ...]) expression
W poniższym przykładzie pokazano zarówno AddressOf
, jak i wyrażenia lambda, które są używane do określania odwołania do delegata.
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 funkcji musi być zgodny z typem delegata. Aby uzyskać więcej informacji na temat wyrażeń lambda, zobacz Wyrażenia lambda. Więcej przykładów wyrażeń lambda i przypisywania AddressOf
do delegatów można znaleźć w Zrelaksowanej konwersji delegatów.
Tematy pokrewne
Nazwa | Opis |
---|---|
Jak wywołać metodę delegata | Zawiera przykład pokazujący, jak skojarzyć metodę z delegatem, a następnie wywołać tę metodę za pośrednictwem delegata. |
Porady: przekazywanie procedur do innej procedury w Visual Basic | Pokazuje, jak używać delegatów do przekazywania jednej procedury do innej procedury. |
Rozluźniona konwersja delegatów | Opisuje, jak można przypisywać podprogramy i funkcje do delegatów lub procedur obsługi, nawet gdy ich sygnatury nie są identyczne. |
Wydarzenia | Zawiera omówienie zdarzeń w Visual Basic. |