Qual è il punto di un’espressione lambda?

Dopo aver letto questo articolo , non riesco a capire perché le espressioni lambda siano mai state usate. Per essere onesti, non penso di avere una comprensione adeguata di cosa siano i delegati e i tipi di albero delle espressioni, ma non capisco perché qualcuno userebbe un’espressione lambda invece di una funzione dichiarata. Qualcuno può illuminarmi?

Primo: brevità e località :

Quale preferiresti scrivere, leggere e mantenere? Questo:

var addresses = customers.Select(customer=>customer.Address); 

o:

 static private Address GetAddress(Customer customer) { return customer.Address; } ... a thousand lines later ... var addresses = customers.Select(GetAddress); 

Che senso ha ingombrare il tuo programma con centinaia o migliaia di funzioni a quattro righe quando potresti semplicemente inserire il codice di cui hai bisogno dove ti serve come espressione breve?

Secondo: lambda si chiude su ambiti locali

Quale preferiresti leggere, scrivere e mantenere, questo:

 var currentCity = GetCurrentCity(); var addresses = customers.Where(c=>c.City == currentCity).Select(c=>c.Address); 

o:

 static private Address GetAddress(Customer customer) { return customer.Address; } private class CityGetter { public string currentCity; public bool DoesCityMatch(Customer customer) { return customer.City == this.currentCity; } } .... var currentCityGetter = new CityGetter(); currentCityGetter.currentCity = GetCurrentCity(); var addresses = customers.Where(currentCityGetter.DoesCityMatch).Select(GetAddress); 

Tutto quel codice irritante è scritto per te quando usi un lambda.

Terzo: le interpretazioni delle query vengono riscritte su lambda per te

Quando scrivi:

 var addresses = from customer in customers where customer.City == currentCity select customer.Address; 

viene trasformato nella syntax lambda per te. Molte persone trovano piacevole questa syntax da leggere, ma abbiamo bisogno della syntax lambda per farlo funzionare.

Quarto: i lambda sono opzionalmente dedotti dal tipo

Si noti che non è necessario fornire il tipo di “cliente” nella comprensione delle query sopra o nelle versioni lambda, ma è necessario fornire il tipo del parametro formale quando lo si dichiara come metodo statico. Il compilatore è intelligente nel dedurre il tipo di parametro lambda dal contesto. Ciò rende il tuo codice meno ridondante e più chiaro.

Quinto: Lambdas può diventare alberi di espressione

Supponiamo che tu voglia chiedere a un web server “mandami gli indirizzi dei clienti che vivono nella città attuale”. Vuoi (1) abbattere un milione di clienti dal sito web e fare il filtraggio sul tuo computer client, oppure (2) inviare al sito web un object che dice “la query contiene un filtro sulla città corrente e poi una selezione dell’indirizzo “? Lascia che il server esegua il lavoro e ti invii solo il risultato corrispondente.

Gli alberi di espressione consentono al compilatore di trasformare il lambda in codice che può essere trasformato in un altro formato di query in fase di esecuzione e inviato a un server per l’elaborazione. I piccoli metodi di supporto eseguiti sul client non lo fanno.

Il motivo principale per cui si utilizza un lambda su una funzione dichiarata è quando è necessario utilizzare una parte di informazioni locali nell’espressione di delega. Per esempio

 void Method(IEnumerable students, int age) { var filtered = students.Where(s => s.Age == age); ... } 

Lambdas consente di catturare facilmente lo stato locale da utilizzare all’interno dell’espressione di delegato. Per fare ciò manualmente è necessario molto lavoro perché è necessario dichiarare sia una funzione che un tipo contenente per contenere lo stato. Ad esempio, ecco il precedente senza lambda

 void Method(IEnumerable students, int age) { var c = new Closure() { Age = age }; var filtered = students.Where(c.WhereDelegate); ... } class Closure { public int age; bool WhereDelegate(Student s) { return s.Age == age; } } 

Digitando questo è noioso e sobject a errori. Le espressioni Lambda automatizzano questo processo.

Lasciamo gli alberi di espressione fuori dall’equazione per il momento e fingiamo che i lambda siano solo un modo più breve per scrivere dei delegati.

Questa è ancora una grande vittoria nel campo dei linguaggi tipizzati staticamente come C #, poiché tali linguaggi richiedono un sacco di codice da scrivere per raggiungere obiettivi relativamente semplici. Hai bisogno di confrontare un array di stringhe per lunghezza della stringa? Devi scrivere un metodo per questo. E devi scrivere una class per inserire il metodo. E poi le buone pratiche impongono che questa class debba trovarsi nel proprio file sorgente. In qualsiasi progetto tranne il più piccolo, tutto ciò si aggiunge. Quando parliamo di piccole cose, la maggior parte delle persone vuole un percorso meno dettagliato per raggiungere l’objective e le lambda sono più concise che possono ottenere.

Inoltre, lambda può facilmente creare chiusure (catturare le variabili dall’ambito attuale e prolungarne la durata). Questo non è magico (il compilatore lo fa creando una class nascosta ed eseguendo alcune altre trasformazioni che puoi fare tu stesso), ma è molto più conveniente dell’alternativa manuale.

E poi ci sono gli alberi di espressione: un modo per scrivere codice e fare in modo che il compilatore trasformi questo codice in una struttura dati che può essere analizzata, modificata e persino compilata in fase di runtime. Questa è una funzionalità estremamente potente che apre le porte a funzionalità impressionanti (che considero definitivamente LINQ). E lo ottieni “gratuitamente”.

http://msdn.microsoft.com/en-us/magazine/cc163362.aspx

Ottimo articolo su cosa sono i lambda e perché puoi / dovresti usarli.

Essenzialmente, l’espressione lambda fornisce una scorciatoia per il compilatore per emettere i metodi e assegnarli ai delegati; questo è tutto fatto per te Il vantaggio che si ottiene con un’espressione lambda che non si ottiene da una combinazione di delegato / funzione è che il compilatore esegue l’inferenza automatica del tipo sugli argomenti lambda

Sono pesantemente utilizzati con LINQ, in realtà LINQ sarebbe piuttosto male senza di esso. Puoi fare cose come:

Database.Table.Where (t => t.Field == “Hello”);

Rendono facile passare una semplice funzionalità a un’altra funzione. Ad esempio, potrei voler eseguire una funzione arbitraria, piccola su ogni elemento di una lista (forse lo voglio quadrare, o prendere la radice quadrata, o così via). Piuttosto che scrivere un nuovo ciclo e una funzione per ciascuna di queste situazioni, posso scriverlo una sola volta e applicare la mia funzionalità arbitraria definita in seguito a ciascun elemento.

Lambda rende il codice breve e dolce. Considera i seguenti due esempi:

Studente di class pubblica

 { public string Name { get; set; } public float grade { get; set; } public static void failed(List studentList, isFaild fail) { foreach (Student student in studentList) { if(fail(student)) { Console.WriteLine("Sorry" + " "+student.Name + " "+ "you faild this exam!"); } } } 

il delegato pubblico bool isFaild (Student myStudent);

 class Program { static void Main(string[] args) { List studentsList = new List(); studentsList .Add(new Student { ID = 101, Name = "Rita", grade = 99 }); studentsList .Add(new Student { ID = 102, Name = "Mark", grade = 48 }); Student.failed(studentsList, std => std.grade < 60); // with Lamda } } 

private static bool isFaildMethod (Student myStudent) // without Lambda

{

if (myStudent.grade <60)

  { return true; } else { return false; } }