Ce face event și EventHandler
Un event este un delegat protejat: doar clasa care îl declară îl poate declanșa, iar codul din afară poate doar să adauge sau să scoată handler-e cu += și -=. Așa un obiect anunță schimbări (un buton apăsat, un sold scăzut) fără să știe cine ascultă.
Convenția .NET este tipul EventHandler sau EventHandler<TEventArgs>: primul parametru este obiectul care trimite evenimentul (sender), al doilea datele lui. Declanșarea se face cu Eveniment?.Invoke(this, date), ca să nu apară eroare când nu există abonați.
Abonamentul ține obiectul abonat în viață cât timp trăiește sursa. Dezabonează-te cu -= când abonatul nu mai are nevoie de eveniment, altfel apar scurgeri de memorie.
Exemple
Exemplul 1: Eveniment cu date: sold scăzut
var cont = new Cont(500);
cont.SoldScazut += (sender, sold) => Console.WriteLine($"Atenție: au rămas {sold} lei");
cont.Retrage(200);
cont.Retrage(250);
Console.WriteLine($"Sold final: {cont.Sold}");
class Cont(int sold)
{
public int Sold { get; private set; } = sold;
public event EventHandler<int>? SoldScazut;
public void Retrage(int suma)
{
Sold -= suma;
if (Sold < 100)
SoldScazut?.Invoke(this, Sold);
}
}
Rezultat
Atenție: au rămas 50 lei
Sold final: 50
Exemplul 2: Mai mulți abonați și dezabonare
var senzor = new Senzor();
EventHandler afisaj = (s, e) => Console.WriteLine("Afișaj actualizat");
senzor.Schimbat += afisaj;
senzor.Schimbat += (s, e) => Console.WriteLine("Jurnal scris");
senzor.Masoara();
senzor.Schimbat -= afisaj;
senzor.Masoara();
class Senzor
{
public event EventHandler? Schimbat;
public void Masoara() => Schimbat?.Invoke(this, EventArgs.Empty);
}
Rezultat
Afișaj actualizat
Jurnal scris
Jurnal scris
Greșeli frecvente
cont.SoldScazut = handler;saucont.SoldScazut(...)din afara clasei nu se compilează: evenimentul permite doar+=și-=.- Declanșarea fără
?.aruncăNullReferenceExceptioncând nu există abonați. - O excepție într-un handler oprește și handler-ele de după el.
Comenzi înrudite
delegate: Un delegat este un tip care ține o referință spre o metodă cu o anumită semnătură; poate ține mai multe metode (multicast).Func, Action și Predicate: Tipurile de delegat gata făcute din .NET: Func returnează o valoare, Action nu returnează nimic, Predicate returnează bool.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.