delegate în C# (.NET)

Un delegat este un tip care ține o referință spre o metodă cu o anumită semnătură; poate ține mai multe metode (multicast).

Sintaxă C#
delegate int Operatie(int a, int b);   Operatie op = Aduna;   op += Inmulteste;

Ce face delegate

Cuvântul delegate declară un tip de funcție: ce parametri primește și ce returnează. O variabilă de acel tip poate primi orice metodă compatibilă (după nume, fără paranteze), o lambda sau o metodă anonimă, și se apelează ca o metodă obișnuită sau cu Invoke.

Delegații sunt multicast: cu += adaugi încă o metodă, cu -= o scoți. La apel rulează toate, în ordinea adăugării; dacă delegatul returnează o valoare, rezultatul este cel al ultimei metode.

În cod nou, de obicei folosești direct Func și Action. Un delegat cu nume propriu este util când semnătura are sens în domeniu sau are parametri ref/out, pe care Func nu îi suportă.

Exemple

Exemplul 1: Delegat cu metode și lambda

Operatie op = Aduna;
Console.WriteLine(op(6, 3));

op = Inmulteste;
Console.WriteLine(op.Invoke(6, 3));

op = (a, b) => a - b;
Console.WriteLine(op(6, 3));

static int Aduna(int a, int b) => a + b;
static int Inmulteste(int a, int b) => a * b;

delegate int Operatie(int a, int b);

Rezultat

9
18
3

Exemplul 2: Multicast cu += și -=

Notificare trimite = Email;
trimite += Sms;
trimite("Comanda a fost livrată");

trimite -= Email;
trimite("Factura e disponibilă");

static void Email(string m) => Console.WriteLine($"Email: {m}");
static void Sms(string m) => Console.WriteLine($"SMS: {m}");

delegate void Notificare(string mesaj);

Rezultat

Email: Comanda a fost livrată
SMS: Comanda a fost livrată
SMS: Factura e disponibilă

Greșeli frecvente

  • După ce scoți toate metodele cu -=, delegatul devine null; apelul direct aruncă NullReferenceException.
  • op = Aduna; înlocuiește tot ce era înainte; pentru a adăuga folosește +=.
  • Scoaterea unei lambda cu -= nu funcționează dacă scrii din nou aceeași lambda: este alt obiect. Păstrează lambda într-o variabilă.

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.
  • event și EventHandler: Un eveniment anunță abonații când se întâmplă ceva; din afara clasei te poți doar abona (+=) sau dezabona (-=).
  • Expresii lambda (=>): 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.