С делегатами тесно связано понятие анонимных методов и лямбд. Анонимные методы представляют сокращенную запись методов. Для примера
возьмем код из прошлой главы, где мы задавали обработчики событий для события Put
для переменной класса Client
:
Sub Main() Dim client1 As New Client("John", "Thompson", "City Bank", 200) AddHandler client1.Added, AddressOf Show_Message client1.Put(150) Console.ReadLine() End Sub Private Sub Show_Message(sender As Object, e As AccountEventArgs) Console.WriteLine(e.message) Console.WriteLine("На счет добавлено {0} $", e.sum) End Sub
Мы можем заменить параметр делегата анонимным методом, и тогда определение метода Show_Message нам уже не понадобится:
Sub Main() Dim client1 As New Client("John", "Thompson", "City Bank", 200) AddHandler client1.Added, Sub(sender As Object, e As AccountEventArgs) Console.WriteLine(e.message) Console.WriteLine("На счет добавлено {0} $", e.sum) End Sub client1.Put(150) Console.ReadLine() End Sub
Походи на анонимные методы лямбда-выражения. По сути лямбды представляют собой сокращенную запись анонимных методов, и если бы мы переписали предыдущий пример с использованием лямбд, то он выглядел бы следующим образом:
Sub Main() Dim client1 As New Client("John", "Thompson", "City Bank", 200) AddHandler client1.Added, Sub(sender, e) Console.WriteLine(e.message) Console.WriteLine("На счет добавлено {0} $", e.sum) End Sub client1.Put(150) Console.ReadLine() End Sub
На первый взгляд сокращение выглядит незначительным - мы фактически только убрали типы параметров. Однако в ряде случаев лямбды гораздо больше сокращают объем кода, к тому же предлагают более удобный синтаксис. Лямбды могут употребляться как для функций, так и для подпрограмм:
Dim square = Function(n As Integer) n * n Console.WriteLine(square(4)) Dim sum = Sub(u As Integer, v As Integer) Console.WriteLine(u + v) sum(7, 6)
Лямбды могут представлять как однострочные, так и многострочные выражения:
Dim square = Function(n As Integer) n * n Console.WriteLine(square(4)) Dim division = Function(u As Integer, v As Integer) Return u / v End Function Console.WriteLine(division(10, 5))
Если лямбды являются многострочными выражениями, то они должны заканчиваться словами End Sub/End Function. Кроме того, если многострочное выражение представляет функцию, для возврата значения должно использоваться ключевое слово Return. Причем мы сразу можно передать значение в лямбда-выражение одновременно с его определением:
Console.WriteLine((Function(n As Integer) n * n)(6)) Console.WriteLine((Function(u As Integer, v As Integer) Return u / v End Function)(10, 5))
Также лямбды могут передаваться в качестве параметров в другие методы:
Sub Main() ShowResult(4, Function(n As Integer) n * n) Console.ReadLine() End Sub Sub ShowResult(value As Integer, fun As Func(Of Integer, Integer)) Console.WriteLine("Результат выполнения функции равен: {0}", fun(value)) End Sub
В данном случае используется выражение Func(Of Integer, Integer), вместо которого при вызове данного метода будет подставляться другой метод
или лямбда-выражение. Выражение Of Integer
обозначает, подставляемое лямбда-выражение должно принимать в качестве параметра значение типа Integer.
Последнее объявление Integer
означает, что метод возвращает значение типа Integer. Если бы мы использовали лямбда-выражение с двумя параметрами,
то код бы выглядел так:
Sub Main() ShowResult(4, 5, Function(n As Integer, m As Integer) n * m) Console.ReadLine() End Sub Sub ShowResult(value1 As Integer, value2 As Integer, fun As Func(Of Integer, Integer, Integer)) Console.WriteLine("Результат выполнения функции равен: {0}", fun(value1, value2)) End Sub