Desenvolvimento - C#
Lambda Expressions
Trazendo recurso de linguagens funcionais ao C#, as lambda expressions permitem escrevermos um bloco de código de forma rápida e bem transparente. São uma evolução natural dos métodos anônimos.
por Rafael CamargoIntrodução:
Trazendo recurso de linguagens funcionais ao C#, as lambda expressions permitem escrevermos um bloco de código de forma rápida e bem transparente. São uma evolução natural dos métodos anônimos. Então podemos atribuir tais expressões a delegates. O LINQ (.NET Language Integrated Query) utiliza constantemente as expressões lambda formando então a base das consultas.
Delegates:
Os delegates estão presentes no .NET desde sua primeira versão. Basicamente, eles permitem que uma classe utilize métodos de outra classe em seu contexto. Assim como existem ponteiros para objetos, podemos ver os delegates como ponteiros para métodos. Vamos ver como funciona, na prática, um delegate:
Primeiramente definimos a assinatura do delegate:
public delegate decimal MeuDelegate(decimal Valor);
Estamos definindo um tipo delegate que recebe como parâmetro um decimal e tem como tipo de retorno um decimal. Assim quando criamos um objeto do tipo MeuDelegate ele poderá apontar para qualquer método que tenha essa mesma assinatura. Vejamos:
public static decimal Dobro(decimal Valor)
{
return Valor * 2;
}
public MeuDelegate DelegateDobro = Dobro;
Observe que foi criada uma intância (DelegateDobro) do tipo delegate definido anteriormente (MeuDelegate) e foi atribuído a ele o nome de um método (Dobro). Agora se invocarmos DelegateDobro será executado o método Dobro.
decimal Resultado = DelegateDobro(3);
A variável Resultado recebe então o valor 6 pois o parâmetro 3 foi multiplicado por 2, de acordo com o método Dobro.
Métodos Anônimos:
Uma das evoluções existentes no framework 2.0 lançado no final de 2005 são os métodos anônimos. Eles permitem atribuirmos a um delegate um bloco de código sem a necessidades de criarmos um método assinado (na verdade ele é criado in-line). Veja o código:
public MeuDelegate DelegateDobro = delegate(decimal Valor)
{
return Valor * 2;
};
Da mesma forma, se chamarmos DelegateDobro(3) o retorno será 6.
Lambda Expression:
É a evolução natural dos métodos anônimos. Permitem escrevermos um bloco de código de maneira mais rápida e clara. Vejamos:
public MeuDelegate DelegateDobro = n => n * 2;
Foi atribuído ao DelegateDobro uma expressão que é chamada de expressão lambda. Temos o operador => e o que vem a antes dele é o parâmetro e após é o retorno.
Observe que a assinatura de MeuDelegate pede um decimal como parâmetro e tem como retorno um decimal. Então DelegateDobro recebe uma lambda expression que tem n como parâmetro e n * 2 como retorno. De acordo com a assinatura do delegate implicitamente n é do tipo decimal e n * 2 também é um retorno decimal.
Vejamos, agora, outra assinatura de delegate:
public delegate string MeuDelegate2(string Texto);
Essa assinatura diz que um delegate do tipo MeuDelegate2 recebe e retorna uma string. São infinitas as possibilidades de métodos ou lambdas expressions que esse tipo pode apontar. Podemos, por exemplo, apontar para uma lambda expression que retorne a string passada como parâmetro toda em maiúsculo.
public MeuDelegate2 DelegateTexto = t => t.ToUpper();
Com há inferencia de tipos, o compilador sabe que t é do tipo string pois se espera uma string como parâmetro e t.ToUpper() é o retorno, também seguindo a assinatura.
A grande “sacada” é podermos na classe x definirmos o comportamento de um método da classe y e com as lambdas expressions isso fica muito mais fácil e produtivo. Vimos exemplos muito simples de lambda expressions mas podemos ir muito além e, para finalizar, observe o código abaixo, imagine... e comente.
public delegate decimal DelegateFormula(decimal Idade, decimal Salario, decimal QtdeFilhos, decimal QtdeDependentes);
public DelegateFormula Formula = (i, s, f, d) => s / (4 + i) * 3 - ((d + f) % 2);