EventHandler in C#

Oftmals werden Delegaten als eine Art Benachrichtigungsmechanismus für Objekte eingesetzt. Ein Objekt könnte einen beliebigen Zustand erreichen und dann alle Zielmethoden, auf die ein Delegat verweist, ausführen. Das Ganze ist zwar sehr leicht umsetzbar, aber an der Stelle gibt es bei größeren Projekten oftmals ein Problem: Der Kommunikationsmechanismus wird immer wieder verändert.
Am Anfang mag es vielleicht ausreichen, wenn man zum Beispiel nur ein Datum als Parameter übergeben möchte. Aber wenn man im Laufe der Entwicklung weitere Parameter hinzufügt, muss man die Signaturen von allen Methoden, auf die der Delegat verweisen kann, anpassen. Und das sind oft nicht wenige...

Glücklicherweise hat uns Microsoft ein spezielles Pattern vorgegeben, welches wir für genau solche Fälle verwenden können: den EventHandler.
Der EventHandler ist ein Delegat, der zwei vorgegebene Parameter hat: object sender und EventArgs e. Das Objekt der Klasse EventArgs beinhaltet Daten, die mit dem aktuellen Ereignis zu tun haben. Alternativ können wir auch eine eigene Argumentenklasse definieren. Das Objekt sender beinhaltet den Auslöser des Events. Das könnte zum Beispiel ein Button in WPF sein. Mit diesen 2 vordefinierten Parametern können wir so gut wie alle Fälle abdecken: Wir haben Informationen über den Auslöser des Events und wir können beliebige Informationen in Form einer Argumentenklasse weitergeben. Das folgende Beispiel soll die Funktionsweise des EventHandlers verdeutlichen:

        public class MeineArgumente

        {

            public int Zahl { get; set; }

            public string Text { get; set; }

        }

 

        public delegate void VarianteAlt(int zahl, string text);

        public delegate void VarianteBesser(object sender, MeineArgumente e);


        public static EventHandler VarianteIdeal;

        public static EventHandler<MeineArgumente> VarianteIdealArg;

 

        static void Main(string[] args)

        {

            VarianteAlt del1 = new VarianteAlt(A);

            VarianteBesser del2 = new VarianteBesser(B);

            VarianteIdeal+= C;

 

            VarianteIdealArg += B;

        }

 

        private static void A(int zahl, string text)

        {

            Console.WriteLine("A");

        }

        private static void B(object sender, MeineArgumente e)

        {

            Console.WriteLine("B");

        }

        private static void C(object sender, EventArgs e)

        {

            Console.WriteLine("C");

        }

In diesem Beispiel habe ich 4 Delegaten erstellt: VarianteAlt und VarianteBesser als eigene Delegaten-Typen und zwei EventHandler, davon einer in der generischen Variante.

Dem Delegaten vom Typ VarianteAlt übergeben wir die Methode A, die zwei Parameter benötigt. Der Delegat vom Typ VarianteBesser verwendet das von Microsoft empfohlene Pattern: Ein Objekt für den Auslöser und eine Klasse, in der alle sonstigen Daten, die Übermittelt werden, zusammengesammelt werden (MeineArgumente).
Dieses Pattern gibt es auch bereits in der Form des EventHandlers. Der EventHandler VarianteIdeal verwendet im Vergleich zu VarianteBesser eine eigene Argumentenklasse. Wenn man die Argumentenklasse MeineArgumente weiterverwenden möchte, kann man auch die generische Variante verwenden: VarianteIdealArg.
Aufgrund der identischen Signatur können sowohl VarianteBesser als auch VarianteIdealArg auf die Methode B verweisen.

Der Vorteil des EventHandlers liegt hier klar auf der Hand. Wir müssen uns keinen neuen Delegaten-Typen erstellen und brauchen uns keine Sorgen um die Signaturen machen. Wenn man viele Parameter übergeben muss, bietet sich oftmals die Verwendung einer eigenen Klasse an, die alle Parameter zu einem Objekt vereint. Wie das Ganze dann in Kombination mit den namensgebenden Events aussieht, werde ich in einem künftigen Artikel erleutern.

Kommentare sind geschlossen