CodeGym /Kurse /C# SELF /Erstellen von Events mit Delegates (

Erstellen von Events mit Delegates ( event und delegate)

C# SELF
Level 52, Lektion 1
Verfügbar

1. Einführung

Also, wenn wir im Kontext von C# über ein „Event“ (event) sprechen, meinen wir einen Mechanismus, der erlaubt, sicher ein oder mehrere Objekte darüber zu informieren, dass etwas passiert ist. Events sind keine Magie: unter der Haube sind das Delegates (das Schlüsselwort delegate) mit zusätzlichem Schutz gegen falsche Verwendung.

Stell dir ein YouTube-Abo vor. Der Kanal (das Objekt, das das Event besitzt) hat einen „Abonnieren“-Button — jeder Zuschauer (ein anderes Objekt) kann ihn drücken und auf die Liste der Abonnenten (Delegates/Handler) kommen. Wenn der Autor ein neues Video hochlädt (das Event auslöst), bekommen nur die Abonnenten die Benachrichtigung, und nur der Kanalbesitzer entscheidet, wann das passiert. Wichtig: Zuschauer können sich an- oder abmelden, aber nicht selbst die Benachrichtigung verschicken — das Recht dazu hat nur der Besitzer des Kanals.

Ein bisschen formale Syntax


// Deklaration eines Delegates, das die "Form" des Event-Handlers definiert
public delegate void SimpleEventHandler();

// Deklaration eines Events basierend auf dem Delegate
public event SimpleEventHandler SomethingHappened;

Ganz einfach: event ist das Schlüsselwort zur Deklaration eines Events, und der Typ des Events wird immer durch ein Delegate bestimmt.

2. Erstes einfaches Beispiel: Event „Knopf wurde gedrückt!“

Schritt 1. Definiere das Delegate für Event-Handler


// Event-Handler: gibt nichts zurück, nimmt keine Parameter
public delegate void ButtonClickHandler();

Schritt 2. Klasse mit Event


public class Button
{
    // Event: man kann sich anmelden und abmelden, aber von außen kann es nicht ausgelöst werden
    public event ButtonClickHandler Click;

    // Methode, die den "Knopf drückt"
    public void Press()
    {
        Console.WriteLine("Knopf gedrückt!");
        // Event-Aufruf: alle Abonnenten benachrichtigen
        Click?.Invoke();
    }
}

Achte darauf: das Event ist auf Basis eines Delegates deklariert, und in der Methode Press wird das Event über ?.Invoke() aufgerufen. Warum? Weil das Event null sein kann (niemand hat sich angemeldet), dann ist Click gleich null. Der sichere Aufruf-Operator stellt sicher, dass Handler nur ausgeführt werden, wenn Abonnenten vorhanden sind.

Schritt 3. Anmeldung am Event und Ausführen des Codes


// Beispielnutzung
public class Program
{
    public static void Main()
    {
        var button = new Button();

        // Fügen wir einen "Listener" hinzu (melden uns für das Event an)
        button.Click += OnButtonClicked;
        button.Click += () => Console.WriteLine("Noch ein Handler!");

        button.Press(); // simulieren eines Knopfdrucks

        // Man kann sich auch wieder abmelden
        button.Click -= OnButtonClicked;
        button.Press();
    }

    // Normaler Event-Handler
    public static void OnButtonClicked()
    {
        Console.WriteLine("Handler: Der Knopf wurde gedrückt!");
    }
}

Beim ersten Druck werden beide Handler ausgeführt, beim zweiten nur die Lambda.

3. Unterschiede zwischen Event und Delegate

Bei einem Delegate kann man frei Werte zuweisen und sogar die Liste der Abonnenten komplett ersetzen — jemand könnte etwas schreiben wie button.Click = null und alle vorherigen Abonnements wären weg.

Bei einem Event ist das anders — es ist stärker an das Objekt gebunden. Nur der Besitzer der Klasse, in der das Event deklariert ist, kann es direkt auslösen (zum Beispiel Click() von innen in der Klasse). Jeder andere Code kann nur anmelden mit += oder abmelden mit -=, aber nicht alles auf einmal „nullen“. Das schützt die Kapselung und verhindert, dass das Abosystem „kaputtgemacht“ wird.

4. Signatur: Delegatetypen für Events, Parameter

Die Konvention in .NET ist: Event-Handler bekommen zwei Parameter — object sender (wer das Event ausgelöst hat) und Event-Argumente (EventArgs). Es wird empfohlen, die Delegates EventHandler oder EventHandler<TEventArgs> zu verwenden.

Beispiel: Delegate mit Parametern


public delegate void ButtonClickHandler(object sender, EventArgs e);

EventArgs ist die Basisklasse zur Übertragung zusätzlicher Informationen. Wenn du mehr Daten brauchst, erstellst du eine eigene abgeleitete Klasse.

Wenden wir das auf unseren Knopf an


// Klasse für Event-Argumente
public class ButtonClickEventArgs : EventArgs
{
    public string UserName { get; }

    public ButtonClickEventArgs(string userName)
    {
        UserName = userName;
    }
}

public class Button
{
    public event EventHandler<ButtonClickEventArgs> Click;

    public void Press(string userName)
    {
        Console.WriteLine("Knopf gedrückt!");
        Click?.Invoke(this, new ButtonClickEventArgs(userName));
    }
}

public static void Main()
{
    var button = new Button();
    button.Click += OnButtonClicked;

    button.Press("Bob");
}

public static void OnButtonClicked(object sender, ButtonClickEventArgs e)
{
    Console.WriteLine($"Benutzer {e.UserName} hat den Knopf gedrückt!");
}

5. Visuelle Darstellung: wie ein Event funktioniert


+-------------+
| Benutzer    |
+-------------+
      |
      v
+--------------+
|  Button.Press|
+--------------+
      |
      v
+-----------------+         +------------------------+
|  Aufruf von     |----->---|   Abonnent 1           |
|  Click?         |         +------------------------+
+-----------------+         |   Handler ausführen    |
      |                     +------------------------+
      v
+-----------------+         +------------------------+
|   Wenn Abonnent |----->---|   Abonnent 2           |
|   vorhanden ist |         +------------------------+
      :                     |   Handler ausführen    |
      v                     +------------------------+

— Button.Press löst das Event aus; die Handler der Abonnenten laufen nacheinander.

6. Nützliche Feinheiten

Empfohlene Event-Form in .NET

Verwende EventHandler und EventHandler<TEventArgs>, damit dein Code kompatibel mit Bibliotheken und Tools bleibt. Dieser Ansatz macht die Weiterentwicklung von Events einfacher: du fügst neue Eigenschaften zu deinen EventArgs hinzu, ohne Abonnenten zu brechen.

Dokumentation: EventHandler, event.

Events vs Delegates

Wenn du eine Komponente direkt mit einer bestimmten Methode verbinden willst — reicht ein Delegate (delegate). Wenn verschiedene Teile des Programms sich jederzeit anmelden und abmelden sollen — verwende ein Event (event).

7. Typische Fehler und Stolpersteine beim Erstellen von Events

Fehler Nr.1: Event-Aufruf ohne Prüfung auf null. Wenn ein Event keine Abonnenten hat, führt ein direkter Aufruf zu einer NullReferenceException. Verwende den sicheren Aufruf:


Click?.Invoke(...);

Fehler Nr.2: Versuch, das Event von außerhalb der Klasse auszulösen. Ein Event kann nur innerhalb der Klasse, in der es deklariert ist, ausgelöst werden. Von einer anderen Klasse aus wird der Compiler einen Fehler melden — das schützt die Kapselung.

Fehler Nr.3: Mehrfache Anmeldung desselben Handlers. Wenn derselbe Handler mehrfach angemeldet wird, wird er auch so oft aufgerufen. Das ist eine Besonderheit des Subscription-Mechanismus. Achte auf Duplikate beim += und auf korrektes Abmelden mit -=.

2
Aufgabe
C# SELF, Level 52, Lektion 1
Gesperrt
Implementierung eines einfachen Ereignisses "Button wurde gedrückt"
Implementierung eines einfachen Ereignisses "Button wurde gedrückt"
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION