English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
C# Objektorientiert (OOP)
Ereignisse sind Benachrichtigungen, die ein Objekt sendet, um das Eintreten einer Aktion anzuzeigen. .NET-Ereignisse folgen dem Observer-Design-Pattern. Die Klasse, die Ereignisse löst, wird als
Publisher (Publisher), die Klasse, die Benachrichtigungen erhält, wird als Subscriber (Abonnent) bezeichnet. Ein Ereignis kann mehrere Abonnenten haben. Normalerweise löst der Publisher ein Ereignis aus, wenn eine bestimmte Aktion erfolgt. Abonnenten möchten Benachrichtigungen erhalten, wenn eine Aktion erfolgt, sie sollten sich bei dem Ereignis anmelden und es verarbeiten.
In C# sind Ereignisse verpackte Delegaten. Es hängt von Delegaten ab. Delegaten definieren die Signatur des Ereignishandlers für die Klasse des Abonnenten.
Durch Ereignisse die Delegaten verwenden Publisher(publisher) Klasse. Andere Klassen, die dieses Ereignis akzeptieren, werden als Abonnenten(subscriber) Klassen bezeichnet. Ereignisse werden in der Klasse deklariert und generiert und durch die Verwendung von Delegaten und Ereignishandlern in derselben Klasse oder anderen Klassen miteinander verknüpft. Klassen, die Ereignisse enthalten, werden verwendet, um Ereignisse zu veröffentlichen. Dies wird als Veröffentlichen-Abonnieren(publisher-subscriber) Modell.
Publisher(publisher)- Es ist ein Objekt, das Ereignisse und Delegaten definiert. Der Zusammenhang zwischen Ereignissen und Delegaten wird ebenfalls in diesem Objekt definiert. Objekte der Klasse Publisher rufen dieses Ereignis auf und informieren andere Objekte.
Abonnent- Ist ein Objekt, das Ereignisse akzeptiert und Ereignishandler bereitstellt. Der Delegat im Publisher-Klasse ruft die Methode im Subscriber-Klasse (Ereignishandler) auf.
Ein Ereignis kann in zwei Schritten deklariert werden:
Delegierten deklarieren
Variable für den Delegierten mit dem Schlüsselwort event deklarieren
Der folgende Beispiel zeigt, wie ein Ereignis in der Publisher-Klasse deklariert wird.
public delegate void Notify(); // Delegat public class ProcessBusinessLogic { public event Notify ProcessCompleted; // Ereignis }
Im obigen Beispiel wurde ein Delegierter Notify deklariert und die Methode Notify im ProzessBusinessLogic-Klasse mit dem Schlüsselwort "event" als Ereignis ProcessCompleted deklariert. Daher wird die Klasse ProcessBusinessLogic als Publisher (Veröffentlicher) bezeichnet. Der Delegierte Notify spezifiziert die Signatur des Ereignishandlers für das Ereignis ProcessCompleted. Es wird angegeben, dass die Ereignishandlingsmethoden der Klasse Subscriber (Abonnent) void als Rückgabetyp haben müssen und keine Parameter haben.
Lassen Sie uns nun sehen, wie das Ereignis ProcessCompleted ausgelöst wird. Sehen Sie sich die folgende Implementierung an.
public delegate void Notify(); // Delegat public class ProcessBusinessLogic { public event Notify ProcessCompleted; // Ereignis public void StartProcess() { Console.WriteLine("Process Started!"); // Einige Code hier... OnProcessCompleted(); } protected virtual void OnProcessCompleted() //Geschützter virtueller Methoden { //Wenn ProcessCompleted nicht null ist, wird der Delegierte aufgerufen ProcessCompleted?.Invoke(); } }
Oben ruft die Methode StartProcess() am Ende die Methode onProcessCompleted() auf, was ein Ereignis auslöst. Normalerweise sollte ein Ereignis mit einem geschützten und virtuellen Methodennamen definiert werden, der auf <EventName> verweist. Geschützt und virtuell ermöglichen es abgeleiteten Klassen, die Logik zum Auslösen von Ereignissen zu überschreiben. Abgeleitete Klassen sollten jedoch immer die Methode On<EventName> der Basisklasse aufrufen, um sicherzustellen, dass die registrierten Delegierten das Ereignis erhalten.
Die Methode OnProcessCompleted() ruft den Delegierten ProcessCompleted?.invoke() auf. Dies ruft alle auf dem Ereignis ProcessCompleted registrierten Ereignishandlermethoden auf.
Die Abonnentenklasse muss sich an das Ereignis ProcessCompleted anmelden und es mit einer Methode behandeln, die der Signatur des Notify-Delegaten entspricht, wie folgt.
class Program { public static void Main() { ProcessBusinessLogic bl = new ProcessBusinessLogic(); bl.ProcessCompleted += bl_ProcessCompleted; // Ereignisregistrierung bl.StartProcess(); } // Ereignisbehandler public static void bl_ProcessCompleted() { Console.WriteLine("Prozess abgeschlossen!"); } }
Oben, die Klasse Program ist ProcessCompleted Abonnenten des Ereignisses. Es verwendet + = Operator zur Ereignisregistrierung. Denken Sie daran, dass dies auf die gleiche Weise ist, wie wir Methoden in die Aufrufliste eines Multicast-Delegaten hinzufügen. Die Methode bl_processcompleted() behandelt das Ereignis, da sie der Signatur des Notify-Delegaten entspricht.
.NET Framework enthält für die häufigsten Ereignisse eingebettete Delegattypen EventHandler und EventHandler <TEventArgs>. Normalerweise sollten alle Ereignisse zwei Parameter enthalten: Ereignisquelle und Ereignisdaten. Für alle Ereignisse, die keine Ereignisdaten enthalten, wird der EventHandler-Delegat verwendet. Für Ereignisse, die Daten an den Verarbeitungshandler senden müssen, wird der EventHandler<TEventArgs>-Delegat verwendet.
Der gezeigte Beispiel kann den EventHandler-Delegat verwenden, ohne eine benutzerdefinierte Notify-Delegat zu deklarieren, wie folgt.
class Program { public static void Main() { ProcessBusinessLogic bl = new ProcessBusinessLogic(); bl.ProcessCompleted += bl_ProcessCompleted; // Ereignisregistrierung bl.StartProcess(); } // Ereignisbehandlung public static void bl_ProcessCompleted(object sender, EventArgs e) { Console.WriteLine("Prozess abgeschlossen!"); } } public class ProcessBusinessLogic { // Verwenden Sie die eingebauten EventHandler zur Ereignisdeklaration public event EventHandler ProcessCompleted; public void StartProcess() { Console.WriteLine("Process Started!"); // Einige Code hier... OnProcessCompleted(EventArgs.Empty); //Keine Ereignisdaten } protected virtual void OnProcessCompleted(EventArgs e) { ProcessCompleted?.Invoke(this, e); } }
Im obigen Beispiel enthält die Methode bl_ProcessCompleted() des Ereignisbehandlers zwei Parameter, die mit dem EventHandler-Delegat übereinstimmen. Gleichzeitig wird this als Absender und EventArgs übergeben. Wenn wir den Event in der Methode OnProcessCompleted() mit Invoke() auslösen, ist er leer. Da unser Ereignis keine Daten benötigt, sondern nur den Abonnenten benachrichtigt, dass der Prozess abgeschlossen ist, haben wir EventArgs.Empty übergeben.
Die meisten Ereignisse senden einigen Daten an die Abonnenten. Die EventArgs-Klasse ist die Basisklasse für alle Ereignisdatenklassen. .NET enthält viele eingebettete Ereignisdatenklassen, wie z. B. SerialDataReceivedEventArgs. Es wird das Namensmuster befolgt, bei dem alle Ereignisdatenklassen mit EventArgs enden. Sie können durch Ableiten von EventArgs benutzerdefinierte Ereignisdatenklassen erstellen.
Übergeben Sie Daten an den Handler wie folgt, indem Sie EventHandler<TEventArgs> verwenden.
class Program { public static void Main() { ProcessBusinessLogic bl = new ProcessBusinessLogic(); bl.ProcessCompleted += bl_ProcessCompleted; // Ereignisregistrierung bl.StartProcess(); } // Ereignisbehandlung public static void bl_ProcessCompleted(object sender, bool IsSuccessful) { Console.WriteLine("Process " + (IsSuccessful ? "Completed Successfully" : "failed")); } } public class ProcessBusinessLogic { // Verwenden Sie die eingebauten EventHandler zur Ereignisdeklaration public event EventHandler<bool> ProcessCompleted; public void StartProcess() { try { Console.WriteLine("Process Started!"); // Einige Code hier... OnProcessCompleted(true); } catch(Exception ex) { OnProcessCompleted(false); } } protected virtual void OnProcessCompleted(bool IsSuccessful) { ProcessCompleted?.Invoke(this, IsSuccessful); } }
Im obigen Beispiel übergeben wir einen einzelnen Boolean-Wert an den Handler, um anzuzeigen, ob der Prozess erfolgreich abgeschlossen wurde.
Wenn mehrere Werte als Ereignisdaten übergeben werden sollen, kann eine Klasse erstellt werden, die von der Basisklasse EventArgs abgeleitet ist, wie folgt.
class ProcessEventArgs : EventArgs { public bool IsSuccessful { get; set; } public DateTime CompletionTime { get; set; } }
Der folgende Beispiel zeigt, wie man eine benutzerdefinierte ProcessEventArgs-Klasse an den Handler weitergibt.
class Program { public static void Main() { ProcessBusinessLogic bl = new ProcessBusinessLogic(); bl.ProcessCompleted += bl_ProcessCompleted; // Ereignisregistrierung bl.StartProcess(); } // Ereignisbehandlung public static void bl_ProcessCompleted(object sender, ProcessEventArgs e) { Console.WriteLine("Process " + (e.IsSuccessful ? "Completed Successfully" : "failed")); Console.WriteLine("Completion Time: " + e.CompletionTime.ToLongDateString()); } } public class ProcessBusinessLogic { // Verwenden Sie die eingebauten EventHandler zur Ereignisdeklaration public event EventHandler<ProcessEventArgs> ProcessCompleted; public void StartProcess() { var data = new ProcessEventArgs(); try { Console.WriteLine("Process Started!"); // Einige Code hier... data.IsSuccessful = true; data.CompletionTime = DateTime.Now; OnProcessCompleted(data); } catch(Exception ex) { data.IsSuccessful = false; data.CompletionTime = DateTime.Now; OnProcessCompleted(data); } } protected virtual void OnProcessCompleted(ProcessEventArgs e) { ProcessCompleted?.Invoke(this, e); } }
Daher können Sie Ereignisse in C# erstellen, auslösen, registrieren und verarbeiten.
Ereignisse sind eine Verpackung von Delegaten. Dies hängt vom Delegaten ab.
Verwenden Sie das Schlüsselwort "event" zusammen mit dem Delegatentypen-Variablen, um Ereignisse zu deklarieren.
Verwenden Sie die eingebauten DelegatenEventHandler oderEventHandler <TEventArgs> wird für häufige Ereignisse verwendet.
Der Publisher-Klasse wird ein Ereignis ausgelöst, während die Subscriber-Klasse ein Ereignis registriert und einen Ereignisbehandlungsmechanismus bereitstellt.
Nennen Sie die Methode, die das Ereignis auslöst, nach dem Ereignisnamen, und verwenden Sie "On" als Präfix.
Die Signatur des Ereignisverarbeiters muss mit der Signatur des Delegaten übereinstimmen.
Verwenden Sie+ Der =-Operator registriert Ereignisse. Verwenden Sie -Der =-Operator löst das Abonnement auf, der =-Operator kann nicht verwendet werden.
Übergeben Sie Ereignisdaten mit EventHandler <TEventArgs>.
Erstellen Sie eine benutzerdefinierte Ereignisdatenklasse, indem Sie die Basisklasse EventArgs ableiten.
Ereignisse können als statisch, virtuell, endgültig und abstrakt deklariert werden (static, virtual, sealed, abstract).
Eine Schnittstelle kann Ereignisse als Mitglieder enthalten.
Wenn es mehrere Abonnenten gibt, wird der Ereignisverarbeiter synchron aufgerufen.