lambda expressions

Post on 11-Jun-2015

993 Views

Category:

Documents

8 Downloads

Preview:

Click to see full reader

DESCRIPTION

Apresentação utilizada para a apresentação do InfoTech2012 onde apresentamos a utilização de lambda e os benefícios de sua utilização.

TRANSCRIPT

LAMBDA EXPRESSIONS

Charles Fortes | Marcus Coelho17 de Maio de 2012

@CharlesFortes

EXPRESSÕES LAMBDA

Uma expressão lambda é em sua essência uma função anônima.

Estas funções anônimas são geralmente passadas como argumentos para outras funções de mais auto nível...

...por característica, podem acessar variáveis no escopo da função na qual ela está declarada

MinhaList.ForEach(item => {var result = FacaAlgo(item);

if (result > 5)FacaOutraCoisa();

});

MinhaList.ForEach(item => FacaAlgo);

FacaAlgo(item){ return ++item;}

FacaAlgo(item){ MessageBox.Show(item);}

Suporte a Lambda Expressions nas Linguagens:

LAMBDA NO .NET

No .Net, todas as expressões lambda usam o operador "=>" (que se lê "vai para" segundo a documentação oficial)

O lado esquerdo da expressão contem os

parâmetros de entrada, enquanto o lado direito possui a expressão ou bloco de instruções

Func<int, bool> myFunc = x => x == 5;

bool result = myFunc(4); //retorna falso

O uso mais comum são em métodos de consultas LINQ

var result = minhaListaDeClientes.Where(cliente => cliente.Endereco.Estado == Estados.Acre).select(cliente => cliente.Nome);

retorna uma lista de strings com o nome de todos os clientes do acre

public void Teste(){ string[] nomes = { "Joao", ... };

var resultado = nomes.Where( delegate (string nome) { return nome != null && nome.StartsWith("J"); } );}

public void Teste(){ string[] nomes = { "Joao", ... };

var resultado = nomes.Where( (string nome) => { return nome != null && nome.StartsWith("J"); } );}

public void Teste(){ string[] nomes = { "Joao", ... };

var resultado = nomes.Where(Filtro);}

public bool Filtro(string nome){ return nome != null && nome.StartsWith("J");}

public void Teste(){ string[] nomes = { "Joao", ... };

var resultado = nomes.Where( nome => nome != null && nome.StartsWith("J") );}

{ string[] nomes = { "Joao", ... }; string filtro = "J"; var resultado = nomes.Where( nome => nome != null && nome.StartsWith(filtro) );}

public void Teste()

public void Teste(){ string[] nomes = { "Joao", ... };

var resultado = nomes.Where(Filtro);}

delegate (string nome){ return nome != null && nome.StartsWith("J");}

O método “Where”, por exemplo, está disponível para todas as coleções do .NET e recebe como parâmetro um método que será utilizado

internamente para avaliar cada item da coleção e verificar se cada item atende a um critério especificado.

Muitos métodos do .NET Framework pedem como

parâmetro um delegate, ou seja, um objeto que poderá chamar indiretamente um outro método, sem conhecê-lo.

public void Teste(){ string[] nomes = { "Joao", ... }; var resultado = nomes.Where(Filtro);}

public bool Filtro(string nome){ return nome != null && nome.StartsWith("J");}

No exemplo acima, o método “Where” utilizará o método “Filtro” para cada item da coleção “nomes”, verificando se o item atende a uma

condição específica, no caso, se o nome começa com a letra “J”.

No framework 2.0 foram criados os métodos anônimos,

que poderiam ser declarados dentro de outros métodos, como se fossem variáveis.

O método anônimo em comparação a um método convencional:

•não tem modificador de acessibilidade (public, private) ou nome (daí o nome “anônimo”)

•deve ser utilizado somente dentro de outros métodos ou variáveis de escopo de classe;

•utiliza a palavra reservada “delegate”.

public void Teste(){ string[] nomes = { "Joao", ... }; var resultado = nomes.Where(Filtro);}

delegate (string nome){ return nome != null && nome.StartsWith("J");}

public void Teste(){ string[] nomes = { "Joao", ... }; var resultado = nomes.Where(delegate (string nome)

{ return nome != null && nome.StartsWith("J");

});}

Podemos utilizar o método anônimo direto na chamada do método “Where”.

Para transformar um método anônimo em uma lambda expression, basta somente remover a palavra “delegate” e utilizar o símbolo “=>” entre os parâmetros de método, e o corpo.

public void Teste(){ string[] nomes = { "Joao", ... }; var resultado = nomes.Where((string nome) =>

{ return nome != null && nome.StartsWith("J");

});}

Você pode omitir os tipos dos parâmetros nas lambdas expression, deixando somente o nome deste. Quando há somente um único parâmetro, os parênteses também são opcionais.

public void Teste(){ string[] nomes = { "Joao", ... }; var resultado = nomes.Where(nome =>

{ return nome != null && nome.StartsWith("J");

});}

Quando sua lambda expression possui somente uma linha que retorna o resultado do método, você pode omitir também as

chaves, a palavra reservada “return” e o ponto-e-vírgula que finaliza a linha de comando.

public void Teste(){ string[] nomes = { "Joao", ... }; var resultado = nomes.Where(nome => nome != null && nome.StartsWith("J"));}

Lambdas expressions podem possuir nenhum ou vários parâmetros...

x => x > 3;

(x, y) => x + y;

() => 1;

...e para que executem mais de um comando, basta colocá-los entre chaves

x => { x++; return x; }

Um exemplo de uso para a lambda expression é a utilização para tratar eventos de controles:

public void Teste(){ buttonSalvar.Click += (obj, args) => labelMensagem = "Registro salvo com sucesso";}

Vantagens ao usar

Ao se usar uma lambda expression, seu código mais legível, menor, mais auto-explicativo...

Além disto, obtem-se mais desempenho pois são feitas

otimizações pelo compilador

Vamos fazer um teste simples

checar se um item pertence a lista, se pertencer adiciona em uma segunda lista através de um método

Há várias formas de fazer isto - inclusive de forma melhor - mas escolhemos a que

achamos ser simples de ser compreendida por todos, e ilustrasse a ideia

Método chamado caso o item exista na lista:

static long add(List<long>dest, long i) { dest.Add(i); return i; }

for (var i = 0; i < listaA.Count; i++ ) { if (listaB.Contains(listaA[i])) add(dest, listaA[i]); }

foreach (var t in listaA) { if (listaB.Contains(t)) add(dest, t); }

var x = (from t in listaA where listaB.Contains(t) select add(dest, t)).ToList();

listaA.Where(t => listaB.Contains(t)).Select(t => add(dest, t));

Fazendo a mesma coisa de várias formas

Tempo gasto

EXPRESSÕES DINÂMICAS

Através da classe Expression podemos criar lambda expressions dinamicamente.

Classes específicas representam cada parte da expressão.

c => c.Codigo == 1

<LambdaExpression>

c

<ParameterExpression>

c.Codigo == 1

<BinaryExpression>

c.Codigo

<MemberExpression>

1

<ConstantExpression>

PERGUNTAS?

@CharlesFortes

top related