![]() |
Лямбды выраженийDate: 2015-10-07; view: 397. Термин «лямбда» поначалу звучит устрашающе, но лямбда — это просто функция, определенная внутри другой функции. Лямбда-выражения — отличный способ компактного выражения локальной логики без распределения по нескольким методам. Например, вот как выглядел бы предыдущий код в Visual Basic 2005 (где нет поддержки лямбда-выражений): Dim query = Array.FindAll(customers, AddressOf Filter)
...
Function Filter(ByVal c As customer) As Boolean Return c.Country = "Canada" End Function Увы, лямбда-выражения в Visual Basic 2008 требовали, чтобы выражения возвращали какое-то значение, поэтому вот такой код: Array.ForEach(customers, Function(c) Console.WriteLine(c.Country)) привел бы к ошибке компиляции: 'Compile error: "Expression does not produce a value." Console.WriteLine является процедурой типа Sub (void в C#), а значит, не возвращает значение, из-за чего компилятор сообщает об ошибке. Чтобы устранить эту проблему, в Visual Basic 2010 введена поддержка лямбд выражений (statement lambdas), которые являются лямбдами, содержащими одно или более выражений: Array.ForEach(customers, Sub(c) Console.WriteLine(c.Country)) Так как Console.WriteLine не возвращает значение, мы можем просто создать лямбду Sub вместо лямбды Function. Вот другой пример, где используется несколько выражений: Array.ForEach(customers, Sub(c) Console.WriteLine("Country Name:") Console.WriteLine(c.Country) End Sub) При выполнении этот код выводит две строки для каждого клиента. Также обратите внимание: если вы задержите курсор мыши над буквой c в процессе кодирования, то увидите, что компилятор логически определил тип как Customer (можно явно задать тип как c As Customer). Еще одно отличное применение лямбд выражений — динамическое подключение обработчиков событий: AddHandler b.Click, Sub(sender As Object, e As EventArgs) MsgBox("Button Clicked") 'insert more complex logic here End Sub
Кроме одно- и многострочных лямбд Sub, которые вы уже видели, Visual Basic 2010 поддерживает многострочные лямбды Function: Dim query = customers.Where(Function(c) 'Return only customers that have not been saved 'insert more complex logic here Return c.ID = -1 End Function) Другой интересный аспект лямбд выражений — то, как они пересекаются с анонимными делегатами, введенными в Visual Basic 2008. Их часто путают с анонимными методами в C#, хотя с технической точки зрения это вовсе не одно и то же. Анонимные делегаты создаются, когда компилятор Visual Basic логически распознает тип делегата, исходя из сигнатуры метода лямбды: Dim method = Function(product As String) If product = "Paper" Then Return 4.5 'units in stock Else Return 10 '10 of everything else End If End Function
MsgBox(method("Paper")) Этот делегат называется анонимным, потому что появляется не в исходном коде, а только в сгенерированном компилятором. Заметьте, что компилятор логически определил тип возвращаемого значения как Double, когда в исходном коде фактически не было блока As, который сообщал бы тип значения, возвращаемый лямбдой. Компилятор просматривает все выражения return внутри лямбды и видит типы Double (4.5) и Integer (10): 'Notice the "As Single" Dim method = Function(product As String) As Single If product = "Paper" Then Return 4.5 'units in stock Else Return 10 '10 of everything else End If End Function Компилятор запускает свой алгоритм поиска доминантного типа и определяет, что значение «10» можно безопасно преобразовать в тип Double, но преобразовать «4.5» в Integer нельзя, поэтому выбирает Double.
|