Lädt...

Delegates und Events

In C# sind Delegates und Events grundlegende Mechanismen zur Erstellung flexibler, modularer Anwendungen. Ein Delegate ist ein typensicherer Methodenzeiger, der es ermöglicht, Methoden als Parameter zu übergeben, sie zu speichern und dynamisch aufzurufen. Dadurch entsteht eine hohe Flexibilität in der Architektur von Software-Systemen. Events basieren auf Delegates und implementieren das Publisher-Subscriber-Muster, das es Objekten erlaubt, andere Objekte über bestimmte Aktionen zu informieren, während die Kopplung zwischen Komponenten gering bleibt.
Delegates und Events werden insbesondere für benutzerdefinierte Benachrichtigungen, Plugin-Systeme, UI-Interaktionen, Logging-Mechanismen und geplante Aufgaben verwendet. Delegates kapseln Methoden und ermöglichen deren dynamische Ausführung, während Events sicherstellen, dass mehrere Abonnenten auf Benachrichtigungen reagieren können, ohne dass der Publisher die genaue Anzahl oder Art der Abonnenten kennen muss.
In diesem Tutorial lernen Leser, wie man Delegates definiert, instanziiert und aufruft, wie man Events erstellt und abonniert und wie diese Konzepte in praxisnahen Szenarien mit OOP-Prinzipien, Datenstrukturen und effizienten Algorithmen angewendet werden. Das Beherrschen von Delegates und Events befähigt Entwickler, Muster wie Observer oder Command zu implementieren, ereignisbasierte Architekturen zu gestalten und häufige Probleme wie Speicherlecks oder unsachgemäße Fehlerbehandlung zu vermeiden.

Grundlegendes Beispiel

text
TEXT Code
using System;

namespace DelegatesAndEventsDemo
{
// Delegate Definition
public delegate void NotificationHandler(string message);

// Publisher Klasse mit Event
public class Publisher
{
public event NotificationHandler Notify;

public void SendNotification(string message)
{
Notify?.Invoke(message);
}
}

// Subscriber Klasse
public class Subscriber
{
private string _name;

public Subscriber(string name)
{
_name = name;
}

public void OnNotificationReceived(string message)
{
Console.WriteLine($"{_name} hat die Nachricht erhalten: {message}");
}
}

class Program
{
static void Main(string[] args)
{
Publisher publisher = new Publisher();

Subscriber alice = new Subscriber("Alice");
Subscriber bob = new Subscriber("Bob");

publisher.Notify += alice.OnNotificationReceived;
publisher.Notify += bob.OnNotificationReceived;

publisher.SendNotification("Hallo an alle Abonnenten!");

publisher.Notify -= bob.OnNotificationReceived;
publisher.SendNotification("Zweite Nachricht");

Console.ReadLine();
}
}

In diesem Beispiel definiert der Delegate NotificationHandler die Signatur der Methoden, die dem Event zugeordnet werden können, wodurch Typsicherheit gewährleistet ist. Die Publisher-Klasse enthält das Event Notify und ruft es mit dem bedingten Operator ?. auf, sodass die Invocation nur erfolgt, wenn Abonnenten existieren.
Die Subscriber-Klasse implementiert die Methode OnNotificationReceived, die mit dem Delegate kompatibel ist. Im Hauptprogramm werden Publisher- und Subscriber-Objekte erstellt, die Events abonniert und ausgelöst, sowie ein Abonnement entfernt, um Speicherlecks zu vermeiden.
Dieses Beispiel demonstriert fortgeschrittene Konzepte wie typisierte Delegates, Event-Kapselung, Entkopplung der Komponenten und sichere Invocation. Es zeigt auch die Praxisrelevanz in Projekten, in denen mehrere Objekte auf dieselbe Benachrichtigung reagieren müssen.

Praktisches Beispiel

text
TEXT Code
using System;
using System.Collections.Generic;

namespace DelegatesAndEventsAdvanced
{
public delegate void DataProcessedHandler(int result);

public class DataProcessor
{
public event DataProcessedHandler DataProcessed;

public void ProcessData(List<int> data)
{
int sum = 0;
foreach (var num in data)
{
if (num < 0)
{
Console.WriteLine("Ungültige Zahl ignoriert: " + num);
continue;
}
sum += num;
}

DataProcessed?.Invoke(sum);
}
}

public class Logger
{
public void LogResult(int result)
{
Console.WriteLine($"Ergebnis protokolliert: {result}");
}
}

public class Notifier
{
public void SendAlert(int result)
{
if (result > 50)
Console.WriteLine("Alarm! Ergebnis überschreitet den Schwellenwert: " + result);
}
}

class Program
{
static void Main(string[] args)
{
DataProcessor processor = new DataProcessor();
Logger logger = new Logger();
Notifier notifier = new Notifier();

processor.DataProcessed += logger.LogResult;
processor.DataProcessed += notifier.SendAlert;

List<int> sampleData = new List<int> { 10, 20, 30, -5 };
processor.ProcessData(sampleData);

Console.ReadLine();
}
}

Dieses erweiterte Beispiel zeigt die praktische Anwendung von Delegates und Events in einem realen Szenario. DataProcessor berechnet die Summe einer Zahlenliste und handhabt negative Werte. Das Event DataProcessed erlaubt mehreren Abonnenten, wie Logger und Notifier, auf das Ergebnis zu reagieren, ohne dass der Producer deren Anzahl oder Typ kennt – eine Implementierung des Observer-Musters.
Jeder Abonnent hat eine spezifische Aufgabe: Logger protokolliert Ergebnisse, Notifier sendet Alerts bei Überschreitung eines Schwellenwerts. Best Practices wie sichere Invocation, Single Responsibility Principle, Entkopplung der Komponenten und effektive Fehlerbehandlung werden eingehalten. Dieses Muster ist anwendbar in ereignisbasierten Analyse-Systemen, Plugin-Frameworks und asynchronen Benachrichtigungssystemen.

Best Practices und Fallstricke:
In C# sollten typisierte Delegates und encapsulierte Events verwendet werden, um Abonnements sicher zu verwalten. Die bedingte Invocation (?.) verhindert NullReferenceException. Abonnements sollten aufgehoben werden, sobald sie nicht mehr benötigt werden, um Speicherlecks zu vermeiden, besonders bei langlebigen Objekten.
Häufige Fehler sind das Abonnieren anonym definierter Delegates ohne Deregistrierung oder das Aufrufen lang laufender Events im Hauptthread, was die Anwendung blockieren kann. Exceptions der Abonnenten sollten behandelt werden, um Stabilität zu gewährleisten. Für Optimierung empfiehlt es sich, Delegates in hochfrequenten Events zu minimieren und Objektallokationen innerhalb von Schleifen zu vermeiden. Datenvalidierung bei Events garantiert die Integrität des Systemzustands. Visual Studio Diagnose-Tools helfen bei der Erkennung von Speicher- oder Event-Problemen.

📊 Referenztabelle

C# Element/Concept Description Usage Example
Delegate Typensicherer Methodenzeiger public delegate void MyDelegate(int x);
Event Benachrichtigungsmechanismus basierend auf Delegate public event MyDelegate MyEvent;
Subscription Hinzufügen einer Methode zum Event myPublisher.MyEvent += mySubscriber.MyMethod;
Unsubscription Entfernen einer Methode zur Vermeidung von Leaks myPublisher.MyEvent -= mySubscriber.MyMethod;
Conditional Invocation Sicheres Aufrufen eines Events MyEvent?.Invoke(42);
Anonymous Delegate Inline Definition eines Delegates myPublisher.MyEvent += (x) => Console.WriteLine(x);

Zusammenfassung und nächste Schritte:
Delegates und Events sind entscheidend für die Erstellung flexibler und modularer C#-Anwendungen. Wichtige Konzepte sind typisierte Delegates, Event-Definition, sichere Subscription/Deregistration und Anwendung des Observer-Musters. Sie ermöglichen Callbacks, modulare Architektur und Event-getriebene Systeme.
Für weiterführende Themen sollten Entwickler fortgeschrittene Events, asynchrone Programmierung mit async/await und Integration von Delegates in LINQ oder funktionale Programmierung erkunden. Praxisnahe Anwendungen in Benachrichtigungssystemen, Plugin-Frameworks und Daten-Pipelines festigen das Verständnis. Ressourcen wie Microsoft Docs, Design Pattern Bücher und Open-Source-Projekte unterstützen die Vertiefung. Die Beherrschung von Delegates und Events ist ein wesentlicher Schritt von der Basisprogrammierung hin zu robusten, wartbaren Softwarearchitekturen.

🧠 Testen Sie Ihr Wissen

Bereit zum Start

Test Your Knowledge

Test your understanding of this topic with practical questions.

4
Fragen
🎯
70%
Zum Bestehen
♾️
Zeit
🔄
Versuche

📝 Anweisungen

  • Lesen Sie jede Frage sorgfältig
  • Wählen Sie die beste Antwort für jede Frage
  • Sie können das Quiz so oft wiederholen, wie Sie möchten
  • Ihr Fortschritt wird oben angezeigt