Visual Basic em Português

Página pessoal de Jorge Paulino sobre o Visual Basic (VB.NET, ASP.NET, VB6, VBA) e algumas noticias de tecnologia

VB.NET: Lambda Expressions

As Lambda Expressions são funções anónimas que podem conter expressões e declarações, e que podem ser usadas para criar expressões ou Delegates. As Lambda Expressions são uma novidade do Visual Studio 2008, e utilizam métodos anónimos (Anonymous Methods), não sendo por isso necessário declarar o tipo de variáveis usadas. As Lambda Expressions conseguem detectar o tipo de dados usados, sendo por isso necessário definir Option Infer On (está por defeito desta forma).

Um exemplo simples de uma expressão Lambda:

Dim lambda1 As Func(Of Integer, Integer) = Function(x) x * x
Debug.WriteLine(lambda1(2).ToString())

Neste pequena expressão, e criado uma Func Delegate, que irá receber um valor do tipo Integer e devolver como resultado do tipo Integer. Irá depois multiplicar o valor recebido e, neste exemplo, o resultado será 4.

Um exemplo um pouco mais complexo, mas também bastante simples de entender:

Dim lambda2 As Func(Of Integer, String) = _
           Function(x) If(x <= 10, 10, x * x).ToString()

Debug.WriteLine(lambda2(15))

Neste caso, irá ser indicado um Integer e devolvido uma String, sendo efectuada uma verificação. Caso o valor indicado seja menor ou igual a 10, irá devolver 10, caso contrário, irá devolver o dobro do valor indicado. Neste caso o resultado será 255.

Isto é semelhante a criar uma função externa, que faça esta validação, mas apenas numa linha de código.


Mas existem mais aplicações para as expressões Lambda. Por exemplo para atribuir Delegates a um objecto:

Dim btn As New Button() With {.Text = "Go ...", .Name = "New Button"}
Me.Controls.Add(btn)

AddHandler btn.Click, Function(s, ev) _
                                       MessageBox.Show(DirectCast(s, Button).Name)

Este exemplo adiciona um botão ao Form e irá mostrar o nome do botão quando este for clicado. O “s” é o Sender e o “ev” o EventArgs. No entanto, apenas na versão 2010, é possível criar funções mais complexas, com mais linhas, sendo que o C# 3.0 já o permite.

Mas mais alguns exemplos de como as expressões Lambda podem ajudar em simplificar o código. Considerando esta simples classe para demonstração:

' O atributo DebuggerStepThrough() irá fazer que o compilador
' não pare enquanto se está a fazer o debug no código do programa
<Diagnostics.DebuggerStepThrough()> _
Public Class student

    Private m_Name As String
    Public Property
Name() As String
        Get
            Return
m_Name
        End Get
        Set
(ByVal value As String)
            m_Name = value
        End Set
    End Property

    Private
m_Age As Int16
    Public Property Age() As Int16
        Get
            Return
m_Age
        End Get
        Set
(ByVal value As Int16)
            m_Age = value
        End Set
    End Property

End Class

A esta simples classe, apenas com duas propriedades – Name, Age – iremos criar uma lista, do tipo student, e adicionar alguns registos.

' Cria uma nova lista de estudantes (Classe student)
Dim studentList As New List(Of student)

' Adiciona vários registos com idades aleatórias entre os 6 ao 50 anos
Dim rnd As New Random
For x As Short = 0 To 999

    Dim newStudent As New student() With { _
            .Name = "Student "& x.ToString, _
            .Age = CShort(rnd.Next(6, 50))}

    studentList.Add(newStudent)
Next


Ok, com a classe criada e com uma lista do tipo student vamos filtrar informação!Vamos procurar todos os teenagers na lista (dos 13 aos 19).

Alguns exemplos de como podemos filtrar os dados:

Usando Delegates

Criamos uma função no programa, que retorna um resultado booleano:


Function GetTeenagers(ByVal s As student) As Boolean
    Return
s.Age >= 13 And s.Age <= 19
End Function

E depois:

Dim delResult As List(Of student) = _
        studentList.FindAll(New Predicate(Of student)(AddressOf GetTeenagers))

For Each s As student In delResult
    Debug.WriteLine(String.Format("Name: {0}, Age: {1}", s.Name, s.Age))
Next


Usando LINQ to Objects

Dim linqResult = From s As student In studentList _
                 Let st As student = DirectCast(s, student) _
                 Where st.Age >= 13 And st.Age <= 19 _
                 Select st

For Each s As student In linqResult
    Debug.WriteLine(String.Format("Name: {0}, Age: {1}", s.Name, s.Age))
Next

Usando Lambda Expressions

Dim lambdaResult As List(Of student) = _ 
   studentList.Where(Function(s) s.Age >= 13 And s.Age <= 19).ToList()

For Each s As student In lambdaResult
    Debug.WriteLine(String.Format("Name: {0}, Age: {1}", s.Name, s.Age))
Next

Simples e prático!

Além disso podemos ainda, de uma forma bastante simples, fazer algumas operações, como calcular a média de idades ou somar todas as idades:

' Calcula a médias de idades
Dim average = studentList.Average(Function(s) s.Age)
Debug.WriteLine(average.ToString)

' Soma todas as idades
Dim sum = studentList.Sum(Function(s) s.Age)
Debug.WriteLine(sum.ToString)

Ou procurar um registo na studentList:

Dim found = studentList.Find(Function(s) s.Name = "Student 5")
If found IsNot Nothing Then
   
Debug.WriteLine(found.Age.ToString())
End If

Como podem ver, as Lambda Expressions podem simplificar algumas operações no código e versão 2010 do Visual Studio irá potenciar ainda mais a sua utilização.

Estas são algumas das aplicações, mas existem mais, que oportunamente poderei mostrar.

3 comentários:

softclean disse...

Excelente artigo! Não fazia a mínima ideia que o VB.net suportava as funções lambda.

Sem dúvida que vou começar a usá-las para pequenos filtros entre outras funções mais simples sem muito esforço ;)

fLaSh disse...

Muito interessante!
Não sabia que existia.. é um conceito parecido com Lua scripts..

Thank you!

fLaSh disse...

Funciona apenas com .NET 3.5..

Por enquanto meus projectos ficam todos com o .NET 2.0, porque quase toda a gente tem instalado..

É um questão de tempo :)



Microsoft Office Especialist

Membro da Comunidade
Experts-Exchange


Administ. da Comunidade
Portugal-a-Programar



Twitter

Artigos no CodeProject

Artigos no CodeProject
Google-Translate-ChineseGoogle-Translate-Portuguese to FrenchGoogle-Translate-Portuguese to GermanGoogle-Translate-Portuguese to ItalianGoogle-Translate-Portuguese to JapaneseGoogle-Translate-Portuguese to EnglishGoogle-Translate-Portuguese to RussianGoogle-Translate-Portuguese to Spanish

Subscrever Novidades

Endereço de Email:

Delivered by FeedBurner

Seguidores

Histórico