Eu li rapidamente sobre o Microsoft Lambda Expression documentação .
Esse tipo de exemplo me ajudou a entender melhor:
delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
Ainda assim, não entendo por que é uma inovação. É apenas um método que morre quando a "variável de método" termina, certo? Por que devo usar isso em vez de um método real?
delegate
é um C #, sugiro que você leia isso antes de ler o restante desta página: stackoverflow.com/questions/2082615/…Respostas:
Expressões lambda são uma sintaxe mais simples para delegados anônimos e podem ser usadas em qualquer lugar em que um delegado anônimo possa ser usado. No entanto, o oposto não é verdadeiro; As expressões lambda podem ser convertidas em árvores de expressão, o que permite muita mágica, como LINQ to SQL.
A seguir, é apresentado um exemplo de expressão de LINQ to Objects usando delegados anônimos e expressões lambda para mostrar como são mais fáceis para os olhos:
Expressões lambda e delegados anônimos têm uma vantagem em escrever uma função separada: eles implementam fechamentos que permitem passar o estado local para a função sem adicionar parâmetros à função ou criar objetos de uso único.
As árvores de expressão são um novo recurso muito poderoso do C # 3.0 que permite que uma API observe a estrutura de uma expressão em vez de apenas obter uma referência a um método que pode ser executado. Uma API apenas precisa transformar um parâmetro delegado em um
Expression<T>
parâmetro e o compilador gerará uma árvore de expressão de um lambda em vez de um delegado anônimo:chamado como:
torna-se:
Este último receberá uma representação da árvore de sintaxe abstrata que descreve a expressão
x > 5
. O LINQ to SQL depende desse comportamento para poder transformar expressões C # nas expressões SQL desejadas para filtragem / pedido / etc. no lado do servidor.fonte
Funções e expressões anônimas são úteis para métodos pontuais que não se beneficiam do trabalho extra necessário para criar um método completo.
Considere este exemplo:
versus
Estes são funcionalmente equivalentes.
fonte
Eu os achei úteis em uma situação em que desejei declarar um manipulador para algum evento de controle, usando outro controle. Para fazer isso normalmente, você teria que armazenar as referências dos controles nos campos da classe para poder usá-las em um método diferente do que elas foram criadas.
Graças às expressões lambda, você pode usá-lo assim:
Muito facil.
fonte
A lambda limpou a sintaxe de delegado anônimo do C # 2.0 ... por exemplo
Foi feito em C # 2.0 assim:
Funcionalmente, eles fazem exatamente a mesma coisa, é apenas uma sintaxe muito mais concisa.
fonte
Essa é apenas uma maneira de usar uma expressão lambda. Você pode usar uma expressão lambda em qualquer lugar em que possa usar um delegado. Isso permite que você faça coisas assim:
Este código pesquisará na lista uma entrada que corresponda à palavra "olá". A outra maneira de fazer isso é realmente passar um delegado para o método Find, assim:
EDIT :
No C # 2.0, isso pode ser feito usando a sintaxe de delegado anônimo:
O Lambda limpou significativamente essa sintaxe.
fonte
string
ae retorna abool
) como um parâmetro para oFind
próprio método.A Microsoft nos deu uma maneira mais limpa e conveniente de criar delegados anônimos chamados expressões Lambda. No entanto, não há muita atenção sendo prestada à parte de expressões desta declaração. A Microsoft lançou um espaço para nome inteiro, System.Linq.Expressions , que contém classes para criar árvores de expressão com base em expressões lambda. As árvores de expressão são compostas de objetos que representam a lógica. Por exemplo, x = y + z é uma expressão que pode fazer parte de uma árvore de expressão em .Net. Considere o seguinte exemplo (simples):
Este exemplo é trivial. E tenho certeza que você está pensando: "Isso é inútil, pois eu poderia ter criado diretamente o delegado em vez de criar uma expressão e compilá-la em tempo de execução". E você estaria certo. Mas isso fornece a base para as árvores de expressão. Há várias expressões disponíveis nos namespaces Expressions e você pode criar suas próprias. Eu acho que você pode ver que isso pode ser útil quando você não sabe exatamente qual deve ser o algoritmo no design ou no tempo de compilação. Eu vi um exemplo em algum lugar para usar isso para escrever uma calculadora científica. Você também pode usá-lo para sistemas bayesianos ou para programação genética(AI). Algumas vezes na minha carreira, tive que escrever uma funcionalidade semelhante ao Excel que permitia aos usuários inserir expressões simples (adição, subtração, etc.) para operar com os dados disponíveis. Na pré-.Net 3.5, tive que recorrer a alguma linguagem de script externa ao C #, ou tive que usar a funcionalidade de emissão de código na reflexão para criar código .Net rapidamente. Agora eu usaria árvores de expressão.
fonte
Isso evita que os métodos que são usados apenas uma vez em um local específico sejam definidos longe do local em que são usados. Os bons usos são como comparadores de algoritmos genéricos, como classificação, em que você pode definir uma função de classificação personalizada na qual você está chamando a classificação, em vez de forçar a procurar em outro lugar para ver em que está classificando.
E não é realmente uma inovação. O LISP possui funções lambda há cerca de 30 anos ou mais.
fonte
Você também pode encontrar o uso de expressões lambda ao escrever códigos genéricos para atuar em seus métodos.
Por exemplo: Função genérica para calcular o tempo gasto por uma chamada de método. (ou seja
Action
, aqui)E você pode chamar o método acima usando a expressão lambda da seguinte maneira,
A expressão permite que você obtenha valor de retorno do seu método e também dos parâmetros
fonte
A expressão lambda é uma maneira concisa de representar um método anônimo. Os métodos anônimos e as expressões Lambda permitem definir a implementação do método em linha, no entanto, um método anônimo exige explicitamente que você defina os tipos de parâmetros e o tipo de retorno para um método. A expressão lambda usa o recurso de inferência de tipo do C # 3.0, que permite ao compilador inferir o tipo da variável com base no contexto. É muito conveniente, pois economiza bastante digitação!
fonte
Uma expressão lambda é como um método anônimo escrito no lugar de uma instância delegada.
Considere a expressão lambda
x => x * x;
O código de uma expressão lambda pode ser um bloco de instruções em vez de uma expressão.
Exemplo
Nota:
Func
é um delegado genérico predefinido.Referências
fonte
Na maioria das vezes, você está usando apenas a funcionalidade em um só lugar, portanto, criar um método desorganiza a classe.
fonte
É uma maneira de executar pequenas operações e colocá-las muito perto de onde são usadas (não muito diferente de declarar uma variável próxima ao seu ponto de uso). Isso deve tornar seu código mais legível. Ao anonimizar a expressão, você também torna muito mais difícil alguém quebrar o código do cliente se a função for usada em outro lugar e modificada para "aprimorá-la".
Da mesma forma, por que você precisa usar o foreach? Você pode fazer tudo no foreach com um loop for simples ou apenas usando IEnumerable diretamente. Resposta: você não precisa , mas torna seu código mais legível.
fonte
A inovação está no tipo segurança e transparência. Embora você não declare tipos de expressões lambda, elas são inferidas e podem ser usadas por pesquisa de código, análise estática, ferramentas de refatoração e reflexão em tempo de execução.
Por exemplo, antes de você ter usado o SQL e receber um ataque de injeção de SQL, porque um hacker passou uma string em que normalmente era esperado um número. Agora você usaria uma expressão lambda LINQ, que é protegida disso.
A criação de uma API LINQ em delegados puros não é possível, pois requer a combinação de árvores de expressão antes de avaliá-las.
Em 2016, a maioria dos idiomas populares possui suporte à expressão lambda , e o C # foi um dos pioneiros nessa evolução entre os principais idiomas imperativos.
fonte
Esta é talvez a melhor explicação sobre por que usar expressões lambda -> https://youtu.be/j9nj5dTo54Q
Em resumo, é para melhorar a legibilidade do código, reduzir as chances de erros reutilizando em vez de replicar o código e aproveitar a otimização que ocorre nos bastidores.
fonte
O maior benefício das expressões lambda e funções anônimas é o fato de permitir que o cliente (programador) de uma biblioteca / estrutura injete funcionalidade por meio de código na biblioteca / estrutura fornecida (como o LINQ, o ASP.NET Core e muitos outros) de uma maneira que os métodos regulares não podem. No entanto, sua força não é óbvia para um único programador de aplicativos, mas para o que cria bibliotecas que serão usadas posteriormente por outras pessoas que desejam configurar o comportamento do código da biblioteca ou daquele que usa bibliotecas. Portanto, o contexto de usar efetivamente uma expressão lambda é o uso / criação de uma biblioteca / estrutura.
Além disso, como eles descrevem o código de uso único, eles não precisam ser membros de uma classe em que isso levará a mais complexidade de código. Imagine ter que declarar uma classe com foco claro toda vez que quisermos configurar a operação de um objeto de classe.
fonte