Menu
Coddy logo textTech

Delegates und Events

Teil des Abschnitts Objektorientierte Programmierung der C#-Journey von Coddy. Lektion 43 von 70.

Ein delegate ist ein Typ, der eine Referenz auf eine Methode darstellt. Stell dir ihn als eine Variable vor, die anstelle von Daten eine Methode enthält. Dadurch kannst du Methoden als Argumente übergeben, sie in Sammlungen speichern und dynamisch aufrufen.

Du deklarierst einen Delegate, indem du die Methodensignatur angibst, auf die er verweisen kann:

public delegate void Notify(string message);

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

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

Ereignisse bauen auf Delegates auf, um das Publish-Subscribe-Muster zu implementieren. Eine class löst ein Ereignis aus, und andere Klassen können es abonnieren, um Benachrichtigungen zu erhalten. Das Schlüsselwort event beschränkt, wie der Delegate verwendet werden kann – subscribers können nur handler hinzufügen oder entfernen, das Ereignis jedoch nicht direkt auslösen.

public class Button
{
    public event Action Clicked;
    
    public void Click()
    {
        Clicked?.Invoke();  // Benachrichtige alle Abonnenten
    }
}

// Abonnieren
Button btn = new Button();
btn.Clicked += () => Console.WriteLine("Button was clicked!");
btn.Click();  // Button wurde geklickt!

Der Operator += abonniert einen handler, während -= die Abmeldung durchführt. Das pattern ?.Invoke() ruft das event safely nur auf, wenn subscribers vorhanden sind. Events sind grundlegend für GUI-Anwendungen, Game-Engines und jedes System, in dem Objekte auf Änderungen reagieren müssen, ohne eng gekoppelt zu sein.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Temperaturüberwachungssystem, das Delegates und Ereignisse verwendet, um subscribers zu benachrichtigen, sobald sich die Temperatur ändert. Dies ist ein klassisches Beispiel für das publish-subscribe-Muster, das Ereignisse so elegant ermöglichen.

Du organisierst deinen Code über zwei Dateien:

  • TemperatureMonitor.cs: Erstelle eine TemperatureMonitor-class im Monitoring-namespace, die als Publisher fungiert. Dein Monitor sollte:
    • ein privates field zum Speichern der aktuellen Temperatur besitzen
    • ein Ereignis mit Action<int> namens TemperatureChanged deklarieren, das jedes Mal ausgelöst wird, wenn die Temperatur aktualisiert wird
    • eine Temperature-property (int) besitzen, deren setter das private field aktualisiert und das Ereignis mit dem neuen Temperaturwert raises
    Denke daran, das ?.Invoke()-Muster zu verwenden, um das Ereignis nur dann safely auszulösen, wenn subscribers vorhanden sind.
  • Program.cs: Erstelle in deiner Main-Datei eine TemperatureMonitor-Instanz und abonniere zwei verschiedene handler für ihr TemperatureChanged-Ereignis:
    • einen handler, der Folgendes ausgibt: Alert: Temperature is now {value} degrees
    • einen weiteren handler, der Folgendes ausgibt: Logged: {value}
    Nachdem du beide handler abonniert hast, setze die Temperatur zweimal mit Werten aus der Eingabe. Jedes Mal, wenn du die Temperatur setzt, sollten beide handler reagieren.

Du erhältst zwei Eingaben:

  • Erster Temperaturwert (Ganzzahl)
  • Zweiter Temperaturwert (Ganzzahl)

Wenn die Eingaben beispielsweise 25 und 30 lauten, sollte die Ausgabe folgendermaßen aussehen:

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

Beachte, wie das Setzen der Temperature-property automatisch alle subscribers benachrichtigt – der Monitor muss nichts darüber wissen, wer zuhört. Das ist die Stärke des ereignisgesteuerten Ansatzes!

Probier es selbst

using System;
using Monitoring;

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

        // TODO: Erstelle eine TemperatureMonitor-Instanz

        // TODO: Subscribe a handler that prints: "Alert: Temperature is now {value} degrees"

        // TODO: Abonniere einen weiteren Handler, der ausgibt: "Logged: {value}"

        // TODO: Setze die Temperatur auf temp1

        // TODO: Setze die Temperatur auf temp2
    }
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-C#-Compiler