Menu
Coddy logo textTech

Delegati ed eventi

Fa parte della sezione Programmazione orientata agli oggetti del percorso C# di Coddy. Lezione 43 di 70.

Un delegato è un tipo che rappresenta un riferimento a un metodo. Consideralo come una variabile che contiene un metodo invece di dati. Questo ti consente di passare metodi come argomenti, memorizzarli in raccolte e chiamarli dinamicamente.

Dichiari un delegato specificando la firma del metodo a cui può fare riferimento:

public delegate void Notify(string message);

public class Publisher
{
    public void SendAlert(string msg) => Console.WriteLine("Alert: " + msg);
}

// Utilizzo
Notify notifier = new Publisher().SendAlert;
notifier("System started");  // Alert: System started

Gli eventi si basano sui delegati per implementare il modello publish-subscribe. Una classe genera un evento e altre classi possono iscriversi per ricevere notifiche. La parola chiave event limita il modo in cui è possibile usare il delegato: gli iscritti possono solo aggiungere o rimuovere gestori, non invocare direttamente l'evento.

public class Button
{
    public event Action Clicked;
    
    public void Click()
    {
        Clicked?.Invoke();  // Notifica tutti gli iscritti
    }
}

// Iscrizione
Button btn = new Button();
btn.Clicked += () => Console.WriteLine("Button was clicked!");
btn.Click();  // Il pulsante è stato cliccato!

L'operatore += sottoscrive un gestore, mentre -= annulla la sottoscrizione. Il modello ?.Invoke() richiama l'evento in modo sicuro solo se ci sono sottoscrittori. Gli eventi sono fondamentali nelle applicazioni GUI, nei motori di gioco e in qualsiasi sistema in cui gli oggetti devono reagire ai cambiamenti senza un accoppiamento stretto.

challenge icon

Sfida

Facile

Costruiamo un sistema di monitoraggio della temperatura che usa delegati ed eventi per notificare gli iscritti ogni volta che la temperatura cambia. Questo è un classico esempio del modello publish-subscribe, che gli eventi rendono così elegante.

Organizzerai il codice in due file:

  • TemperatureMonitor.cs: crea una classe TemperatureMonitor nello spazio dei nomi Monitoring che funge da editore. Il monitor dovrebbe:
    • Avere un campo privato in cui memorizzare la temperatura corrente
    • Dichiarare un evento usando Action<int> chiamato TemperatureChanged, che viene attivato ogni volta che la temperatura viene aggiornata
    • Avere una proprietà Temperature (int) il cui setter aggiorna il campo privato e attiva l'evento con il nuovo valore della temperatura
    Ricorda di usare lo schema ?.Invoke() per attivare l'evento in modo sicuro solo quando ci sono iscritti.
  • Program.cs: nel file principale, crea un TemperatureMonitor e iscrivi due gestori diversi al suo evento TemperatureChanged:
    • Un gestore che stampa: Alert: Temperature is now {value} degrees
    • Un altro gestore che stampa: Logged: {value}
    Dopo aver iscritto entrambi i gestori, imposta la temperatura due volte usando i valori inseriti. Ogni volta che imposti la temperatura, entrambi i gestori dovrebbero rispondere.

Riceverai due input:

  • Primo valore della temperatura (intero)
  • Secondo valore della temperatura (intero)

Per esempio, se gli input sono 25 e 30, l'output dovrebbe essere:

Alert: Temperature is now 25 degrees
Logged: 25
Alert: Temperature is now 30 degrees
Logged: 30

Nota come l'impostazione della proprietà Temperature notifichi automaticamente tutti gli iscritti: il monitor non deve sapere nulla di chi sta ascoltando. Questa è la bellezza dell'approccio basato sugli eventi!

Provalo tu

using System;
using Monitoring;

class Program
{
    public static void Main(string[] args)
    {
        // Leggi l'input
        int temp1 = Convert.ToInt32(Console.ReadLine());
        int temp2 = Convert.ToInt32(Console.ReadLine());

        // TODO: Crea un'istanza di TemperatureMonitor

        // TODO: Registra un gestore che stampi: "Alert: Temperature is now {value} degrees"

        // TODO: Registra un altro gestore che stampi: "Logged: {value}"

        // TODO: Imposta la temperatura su temp1

        // TODO: Imposta la temperatura su temp2
    }
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore C# online