Ce face Expresii lambda (=>)
O expresie lambda are parametrii în stânga săgeții => și corpul în dreapta: o singură expresie (n => n % 2 == 0) sau un bloc între acolade cu return. Tipurile parametrilor se deduc din context, de obicei din Func<...> sau Action<...> cerut de metodă.
Lambda poate folosi variabilele din jur (closure): le capturează prin referință, deci vede valoarea lor din momentul apelului, nu din momentul creării. Cu static în față (C# 9) compilatorul interzice capturarea.
Din C# 10 o lambda are un tip natural și poate fi pusă într-o variabilă var, iar din C# 12 parametrii pot avea valori implicite: var salut = (string nume = "Ana") => $"Salut, {nume}";.
Exemple
Exemplul 1: Lambda în LINQ și ca variabilă
int[] note = [4, 9, 7, 10, 5];
var promovate = note.Where(n => n >= 5).Select(n => n * 10);
Console.WriteLine(string.Join(", ", promovate));
Func<int, int, int> aduna = (a, b) => a + b;
Console.WriteLine(aduna(3, 4));
var salut = (string nume = "Ana") => $"Salut, {nume}!";
Console.WriteLine(salut());
Console.WriteLine(salut("Mihai"));
Rezultat
90, 70, 100, 50
7
Salut, Ana!
Salut, Mihai!
Exemplul 2: Captură de variabile (closure)
Lambda vede valoarea curentă a lui prag la apel, nu pe cea din momentul în care a fost creată.
int prag = 5;
Func<int, bool> trece = n => n >= prag;
Console.WriteLine(trece(6));
prag = 8;
Console.WriteLine(trece(6));
int contor = 0;
Action numara = () => contor++;
numara();
numara();
Console.WriteLine(contor);
Rezultat
True
False
2
Greșeli frecvente
- Capturarea unei variabile care se schimbă ulterior dă rezultate neașteptate. Copiază valoarea într-o variabilă locală nouă dacă vrei s-o „îngheți”.
- O lambda cu bloc
{ }care trebuie să returneze ceva are nevoie dereturn; varianta fără acolade returnează automat expresia. - Lambda-urile care capturează variabile alocă un obiect la fiecare creare. În bucle foarte rapide, preferă
staticsau o metodă.
Comenzi înrudite
Func, Action și Predicate: Tipurile de delegat gata făcute din .NET: Func returnează o valoare, Action nu returnează nimic, Predicate returnează bool.delegate: Un delegat este un tip care ține o referință spre o metodă cu o anumită semnătură; poate ține mai multe metode (multicast).