Expresii lambda (=>) în C# (.NET)

O funcție scurtă, fără nume, scrisă pe loc: parametri => rezultat. Se folosește în LINQ, la evenimente și oriunde se cere un delegat.

Sintaxă C#
x => x * 2   (a, b) => a + b   () => { ... }

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 de return; varianta fără acolade returnează automat expresia.
  • Lambda-urile care capturează variabile alocă un obiect la fiecare creare. În bucle foarte rapide, preferă static sau 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).