Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Делегаты — это объекты, ссылающиеся на методы. Иногда они описываются как указатели на типобезопасные функции , так как они похожи на указатели функций, используемые в других языках программирования. Но в отличие от указателей функций делегаты Visual Basic являются ссылочным типом на основе класса System.Delegate. Делегаты могут ссылаться на оба общих метода — методы, которые могут вызываться без определенного экземпляра класса — и методов экземпляра.
Делегаты и события
Делегаты полезны в ситуациях, когда требуется посредник между вызывающей процедурой и вызываемой процедурой. Например, может потребоваться, чтобы объект, вызывающий события, мог вызывать различные обработчики событий в различных обстоятельствах. К сожалению, объект, вызывающий события, не может знать заранее, какой обработчик событий обрабатывает определенное событие. Visual Basic позволяет динамически связывать обработчики событий с событиями, создавая делегат для вас при использовании инструкции AddHandler
. Во время выполнения делегат перенаправляет вызовы соответствующему обработчику событий.
Хотя вы можете создать свои делегаты, в большинстве случаев Visual Basic создает делегат и заботится о деталях за вас. Например, Event
инструкция неявно определяет класс делегата с именем <EventName>EventHandler
как вложенный класс в классе, содержащем Event
инструкцию, с такой же подписью, как у события. Оператор AddressOf
неявно создает экземпляр делегата, который ссылается на определенную процедуру. Следующие две строки кода эквивалентны. В первой строке отображается явное создание экземпляра EventHandler
с ссылкой на метод Button1_Click
, отправленный в качестве аргумента. Вторая строка является более удобным способом сделать то же самое.
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
как type
, parm2
как 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. |