Студопедия
rus | ua | other

Home Random lecture






Лямбды выражений


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 lamb­das), которые являются лямбдами, содержащими одно или более выражений:

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.


<== previous lecture | next lecture ==>
Неявное продолжение строки | Автоматически реализуемые свойства
lektsiopedia.org - 2013 год. | Page generation: 0.118 s.