[Ausführliche Erklärung von C#] Kapitel 5: Erweiterte objektorientierte Programmierung: Delegation und Ereignisse

Delegaten und Ereignisse sind wichtige Konzepte in der fortgeschrittenen objektorientierten Programmierung, die verwendet werden, um Programmflexibilität, Skalierbarkeit und Wartbarkeit zu erreichen. Sie spielen unter anderem eine Schlüsselrolle bei der Implementierung von Rückrufen, der Ereignisbehandlung und der asynchronen Programmierung.
Delegaten ermöglichen es uns, eine Methode als Objekt zu behandeln, das als Parameter übergeben, in einer Variablen gespeichert und bei Bedarf aufgerufen werden kann. Diese Fähigkeit macht Delegaten ideal für die Implementierung von Rückruffunktionen, indem sie eine Methode an eine andere übergeben, sodass diese bei Bedarf die erstere aufruft. Die Delegation unterstützt auch das Konzept der Delegationskette und der Multicast-Delegierung. Mehrere Methoden können zu einer Delegationskette verknüpft und nacheinander ausgeführt werden.
Ereignisse sind eine spezielle Form der Delegation, die zur Implementierung des Observer-Musters und der ereignisgesteuerten Programmierung verwendet wird. Ereignisse bieten eine präzise und zuverlässige Möglichkeit, bestimmte Programmereignisse wie Benutzerinteraktionen, Nachrichtenbenachrichtigungen usw. zu verarbeiten und darauf zu reagieren. Durch das Ereignis können wir den Herausgeber und den Abonnenten des Ereignisses definieren. Wenn der Herausgeber das Ereignis auslöst, erhält der Abonnent die Benachrichtigung und führt den entsprechenden Vorgang aus. Dieses lose gekoppelte Entwurfsmuster macht das Programm skalierbarer und wartbarer.
Delegierte und Ereignisse spielen auch bei der asynchronen Programmierung eine wichtige Rolle. Sie können uns dabei helfen, Rückrufe und Benachrichtigungen für asynchrone Vorgänge zu verarbeiten und so die Reaktionsfähigkeit und Effizienz von Programmen zu verbessern. Durch die Kapselung asynchroner Vorgänge in Delegaten oder Ereignissen können wir nach Abschluss asynchroner Vorgänge die entsprechende Verarbeitungslogik ausführen, ohne den Hauptthread zu blockieren oder eine komplexe Thread-Verwaltung durchzuführen.

1. Das Konzept und die grundlegende Verwendung von Vertrauen

1.1 Definition und Merkmale der Betrauung

Ein Delegate ist ein Referenztyp in C#, der es uns ermöglicht, Methoden als Objekte zu behandeln und Methoden als Parameter zu übergeben, sie in Variablen zu speichern und sie bei Bedarf aufzurufen.
Die Definition eines Delegaten umfasst zwei Hauptteile: die Deklaration des Delegatentyps und die Erstellung der Delegateninstanz. Eine Delegattypdeklaration gibt die Signatur der Methode an, einschließlich Parametertypen und Rückgabetyp. Eine Delegate-Instanz ist ein Objekt, das gemäß dem Delegate-Typ erstellt wird und auf eine oder mehrere Methoden verweisen kann. Die Hauptmerkmale der Delegation sind wie folgt:

  1. Delegaten sind typsicher: Der Delegatentyp definiert die Signatur der Methode und nur Methoden mit derselben Signatur können Instanzen des Delegatentyps zugewiesen werden.
  2. Delegation ist zusammensetzbar: Mehrere Methoden können durch Delegationsketten zu einer Delegationskette kombiniert werden. Jede Methode in der Delegationskette kann der Reihe nach aufgerufen werden.
  3. Delegaten sind veränderbar: Methoden können der Delegateninstanz dynamisch hinzugefügt oder daraus entfernt werden. Methoden können mit dem Operator „+“ hinzugefügt und mit dem Operator „-“ entfernt werden.
  4. Der Delegat ist die Grundlage der asynchronen Programmierung: Der Delegat kann zur Verarbeitung der Rückruffunktion des asynchronen Vorgangs verwendet werden, und die entsprechende Verarbeitung wird durch Aufrufen der Delegateninstanz nach Abschluss des asynchronen Vorgangs durchgeführt.

Delegierte spielen eine wichtige Rolle bei der Implementierung von Rückrufen, der Ereignisverarbeitung und der Multithread-Programmierung. Sie bieten eine flexible, erweiterbare und wartbare Möglichkeit, Methodenaufrufe und -kommunikation zu handhaben, wodurch die Programmierung flexibler und erweiterbarer wird.

1.2 Syntax und Delegiertendeklaration

Die Syntax und Deklaration des Delegaten umfasst hauptsächlich die folgenden Schritte:

  1. Definieren des Delegatentyps: Verwenden Sie delegatedas Schlüsselwort, um den Delegatentyp zu definieren. Der Delegattyp definiert die Signatur der Methode, einschließlich Parametertypen und Rückgabetyp. Das Syntaxformat ist wie folgt:

    delegate <返回类型> <委托类型名>(<参数列表>);
    

    Definieren Sie beispielsweise einen Delegate-Typ, der zwei Ganzzahlparameter akzeptiert und eine Ganzzahl zurückgibt:

    delegate int MyDelegate(int x, int y);
    
  2. Erstellen Sie eine Delegate-Instanz: Erstellen Sie eine Delegate-Instanz entsprechend dem Delegate-Typ und weisen Sie der Delegat-Instanz die Methode zu. Delegateninstanzen können mit anonymen Methoden, Lambda-Ausdrücken oder benannten Methoden erstellt werden. Das Syntaxformat ist wie folgt:

    <委托类型> <委托实例名> = new <委托类型>(<方法名>);
    

    Erstellen Sie beispielsweise eine Delegate-Instanz und weisen Sie sie einer benannten Methode zu:

    MyDelegate myDelegate = new MyDelegate(MyMethod);
    
  3. Call Delegate Instance: Verwenden Sie die Delegate-Instanz, um die Methode aufzurufen. Sie kann wie eine normale Methode mithilfe der Delegate-Instanz aufgerufen werden.

    int result = myDelegate(10, 20);
    

    Beim Aufruf einer Delegateninstanz ruft der Delegat diese Methoden in der Reihenfolge der zugehörigen Methoden auf und gibt das Ergebnis der letzten Methode zurück (sofern ein Rückgabewert vorhanden ist).

Vorsichtsmaßnahmen:

  • Die Parameterliste und der Rückgabetyp eines Delegatentyps müssen mit der Signatur der zugehörigen Methode übereinstimmen.
  • Eine Delegate-Instanz kann nur Methoden aufrufen, die dem Delegate-Typ entsprechen. Wenn die Delegate-Instanz eine Methode aufruft, die nicht übereinstimmt, führt dies zu einem Kompilierungsfehler.
  • Ein Delegate-Typ ist ein Referenztyp, und ein Verweis auf eine Methode kann über die Delegate-Instanz übergeben werden, anstatt die Methode direkt aufzurufen.
  • Methoden können mit den Operatoren +=und hinzugefügt und entfernt werden -=. +=Der Operator fügt der Delegationskette eine Methode hinzu und -=der Operator entfernt eine Methode aus der Delegationskette.
1.3 Instanziierung und Aufruf delegieren

Die Instanziierung und der Aufruf des Delegaten umfassen hauptsächlich die folgenden Schritte:

  1. Erstellen Sie eine Delegate-Instanz: Erstellen Sie eine Delegate-Instanz entsprechend dem Delegate-Typ und verknüpfen Sie sie mit einer oder mehreren Methoden. Delegateninstanzen können mit anonymen Methoden, Lambda-Ausdrücken oder benannten Methoden erstellt werden.

    <委托类型> <委托实例名> = new <委托类型>(<方法名>);
    

    Erstellen Sie beispielsweise eine Delegate-Instanz und verknüpfen Sie sie mit einer benannten Methode:

    MyDelegate myDelegate = new MyDelegate(MyMethod);
    
  2. Rufen Sie die Delegateninstanz auf: Rufen Sie die zugehörige Methode über die Delegateninstanz auf. Eine Delegate-Instanz kann wie eine normale Methode aufgerufen werden, indem sie Parameter übergibt und einen Rückgabewert erhält.

    <返回值类型> result = <委托实例名>(<参数列表>);
    

    Verwenden Sie beispielsweise eine Delegate-Instanz, um eine zugehörige Methode aufzurufen:

    int result = myDelegate(10, 20);
    

    Beachten Sie, dass der Aufruf der Delegateninstanz in der Reihenfolge der Methoden in der Delegatenkette erfolgt, wobei jede Methode nacheinander aufgerufen wird und der Rückgabewert der letzten Methode (sofern vorhanden) zurückgegeben wird.

1.4 Delegationskette und Multicast-Delegierung

Eine Delegationskette ist ein Mechanismus zum Kombinieren mehrerer Delegationsinstanzen zu einer logischen Kette. Eine Delegationskette kann durch Kombinieren einer Delegationsinstanz mit einer anderen Delegationsinstanz erstellt werden.
Ein Multicast-Delegat ist ein spezieller Delegatentyp, der mehrere Delegateninstanzen enthalten kann, die nacheinander in der Reihenfolge ihres Hinzufügens aufgerufen werden. Mithilfe der Multicast-Delegierung können Delegierteninstanzen zur Delegiertenkette hinzugefügt oder daraus entfernt werden, wodurch das Verhalten der Delegiertenkette dynamisch erweitert oder geändert wird. In C# können Sie +den Operator verwenden, um mehrere Delegate-Instanzen zu einer Delegate-Kette zusammenzufassen, und -den Operator verwenden, um die Delegate-Instanz aus der Delegate-Kette zu entfernen.
Hier ist ein Beispielcode mit Multicast-Delegaten:

public delegate void MyDelegate();

static void Main()
{
    
    
    MyDelegate myDelegate1 = Method1;
    MyDelegate myDelegate2 = Method2;

    // 创建委托链
    MyDelegate myDelegateChain = myDelegate1 + myDelegate2;

    // 调用委托链中的方法
    myDelegateChain();

    // 从委托链中移除委托实例
    myDelegateChain -= myDelegate2;

    // 再次调用委托链中的方法
    myDelegateChain();
}

static void Method1()
{
    
    
    Console.WriteLine("Method 1");
}

static void Method2()
{
    
    
    Console.WriteLine("Method 2");
}

Ausgabeergebnis:

Method 1
Method 2
Method 1

Im obigen Beispiel handelt es sich bei myDelegate1und myDelegate2um zwei separate Delegateninstanzen. Indem Sie den Operator verwenden +, um sie zu einer Delegationskette zu kombinieren myDelegateChain, werden beim Aufruf der Delegationskette nacheinander die Methoden der beiden Delegateninstanzen aufgerufen. Verwenden Sie anschließend -den Operator, um myDelegate2aus der Delegationskette zu entfernen. Wenn Sie die Delegationskette erneut aufrufen, myDelegate1wird nur die Methode von aufgerufen.
Multicast-Delegates bieten eine bequeme und flexible Möglichkeit, mehrere Delegate-Instanzen zu verarbeiten und ihre Methoden in einer bestimmten Reihenfolge auszuführen. Es ist sehr nützlich in Szenarien wie der Ereignisbehandlung, dem Rückrufmechanismus usw.

2. Beauftragte Anwendungsszenarien

2.1 Rückruffunktion

Ein häufiges Anwendungsszenario der Delegation ist die Rückruffunktion (Callback). Die Rückruffunktion bedeutet, dass das System beim Abschluss einer Operation oder beim Eintreten eines Ereignisses eine vorregistrierte Funktion aufruft, um die entsprechende Logik zu verarbeiten. Durch den Delegationsmechanismus kann eine Funktion als Parameter an eine andere Funktion übergeben werden, sodass diese die eingehende Funktion zu einem geeigneten Zeitpunkt aufrufen kann. Dieser Mechanismus ist in Situationen nützlich, in denen asynchrone Vorgänge, Ereignisbehandlung, Benutzerinteraktion usw. erforderlich sind. Das Folgende ist ein Beispielcode, der eine Rückruffunktion mithilfe von Delegaten implementiert:

public delegate void CallbackFunction(string message);

public class Operation
{
    
    
    public void LongRunningOperation(CallbackFunction callback)
    {
    
    
        // 模拟耗时操作
        Console.WriteLine("开始执行长时间操作...");
        Thread.Sleep(2000);
        Console.WriteLine("长时间操作完成。");

        // 调用回调函数
        callback("操作已完成");
    }
}

public class Program
{
    
    
    static void Main()
    {
    
    
        Operation operation = new Operation();
        operation.LongRunningOperation(OnOperationComplete);
    }

    static void OnOperationComplete(string message)
    {
    
    
        Console.WriteLine("操作回调:" + message);
    }
}

Ausgabeergebnis:

开始执行长时间操作...
长时间操作完成。
操作回调:操作已完成

Im obigen Beispiel führt die Methode Operationin der Klasse LongRunningOperationeinen zeitaufwändigen Vorgang aus und CallbackFunctionruft dann die Rückruffunktion über den übergebenen Parameter des Delegatentyps auf. ProgramDie Methode in der Klasse OnOperationCompletefungiert als Rückruffunktion, die aufgerufen wird und eine Meldung ausgibt, wenn der Vorgang abgeschlossen ist.
Durch die Verwendung von Delegaten und Rückruffunktionen kann der Aufrufer über das Ergebnis oder den Status des Vorgangs benachrichtigt werden und die entsprechende Logik zu einem geeigneten Zeitpunkt ausgeführt werden, wodurch eine flexiblere Programmsteuerung und -interaktion realisiert wird. Rückruffunktionen werden häufig in Szenarien wie asynchroner Programmierung, ereignisgesteuerter Programmierung und Benutzeroberflächeninteraktion verwendet.

2.2 Ereignisverarbeitung

Delegierte werden häufig in der Ereignisabwicklung eingesetzt. Ein Ereignis bezieht sich auf eine bestimmte Aktion oder Zustandsänderung, die in einem Programm auftritt, und die Ereignisverarbeitung ist ein Mechanismus zum Reagieren und Verarbeiten dieser Ereignisse. Durch die Kombination von Delegation und Ereignissen kann ein lose gekoppeltes Entwurfsmuster realisiert werden, also eine ereignisgesteuerte Programmierung. Bei der ereignisgesteuerten Programmierung kommunizieren Objekte durch die Definition von Ereignissen und entsprechenden Delegaten. Wenn ein Ereignis auftritt, wird die beim entsprechenden Delegaten registrierte Methode aufgerufen, um auf das Ereignis zu reagieren. Im Folgenden finden Sie einen Beispielcode für die Ereignisbehandlung mithilfe von Delegaten und Ereignissen:

public class Button
{
    
    
    public event EventHandler Click;

    public void OnClick()
    {
    
    
        // 触发 Click 事件
        Click?.Invoke(this, EventArgs.Empty);
    }
}

public class Program
{
    
    
    static void Main()
    {
    
    
        Button button = new Button();
        button.Click += Button_Click;

        button.OnClick();
    }

    static void Button_Click(object sender, EventArgs e)
    {
    
    
        Console.WriteLine("按钮被点击了!");
    }
}

Ausgabeergebnis:

按钮被点击了!

Im obigen Beispiel Buttondefiniert die Klasse ein ClickEreignis mit dem Namen und verwendet EventHandlerden Delegaten als Typ des Ereignishandlers. ButtonDie Methode in der Klasse OnClickwird verwendet, um Clickdas Ereignis auszulösen und Click?.Invoke(this, EventArgs.Empty)den registrierten Ereignishandler über aufzurufen. In Programder Klasse instanziieren wir ein ButtonObjekt und registrieren die Methode +=über den Operator als Ereignishandler . Anschließend wird durch den Aufruf das Click-Event des Buttons ausgelöst und die entsprechende Event-Handler-Methode ausgeführt. Durch die Verwendung von Delegaten und Ereignissen können wir Ereignisse einfach von der Ereignisverarbeitung entkoppeln und so die Interaktion von Objekten flexibler und erweiterbarer machen. Ereignisgesteuerte Programmiermuster werden häufig in grafischen Benutzeroberflächen (GUI), Benutzerinteraktion, asynchroner Programmierung und anderen Szenarien verwendet.Button_ClickClickbutton.OnClick()

2.3 Asynchrone Programmierung

Der Delegat spielt eine wichtige Rolle bei der asynchronen Programmierung. Er kann bei der Bewältigung zeitaufwändiger Vorgänge helfen und die Leistung und Reaktionsfähigkeit der Anwendung verbessern. Wenn im herkömmlichen synchronen Programmiermodell ein Programm einen zeitaufwändigen Vorgang ausführt, blockiert es den Hauptthread, wodurch die Anwendung nicht mehr reagiert. Das asynchrone Programmiermodell implementiert asynchrone Vorgänge mithilfe von Delegaten, sodass der Hauptthread weiterhin andere Aufgaben ausführen kann, ohne auf den Abschluss zeitaufwändiger Vorgänge warten zu müssen. Das Folgende ist ein Beispielcode für die asynchrone Programmierung mit Delegaten:

public class Worker
{
    
    
    public delegate void WorkCompletedHandler(string result);

    public void DoWorkAsync(WorkCompletedHandler callback)
    {
    
    
        // 模拟耗时操作
        Console.WriteLine("开始执行异步操作...");
        Thread.Sleep(2000);
        string result = "操作已完成";

        // 异步操作完成后调用回调函数
        callback(result);
    }
}

public class Program
{
    
    
    static void Main()
    {
    
    
        Worker worker = new Worker();
        worker.DoWorkAsync(OnWorkCompleted);

        Console.WriteLine("主线程继续执行其他任务...");
        // 等待异步操作完成
        Console.ReadLine();
    }

    static void OnWorkCompleted(string result)
    {
    
    
        Console.WriteLine("异步操作回调:" + result);
    }
}

Ausgabeergebnis:

开始执行异步操作...
主线程继续执行其他任务...
异步操作回调:操作已完成

Im obigen Beispiel simuliert die Methode Workerin der Klasse DoWorkAsynceinen zeitaufwändigen asynchronen Vorgang und WorkCompletedHandlerruft die Rückruffunktion auf, nachdem der Vorgang über den eingehenden Delegate-Typparameter abgeschlossen ist. In Programder Klasse instanziieren wir ein WorkerObjekt, rufen DoWorkAsyncdie Methode auf und übergeben OnWorkCompleteddie Methode als Rückruffunktion. Im Hauptthread können wir weiterhin andere Aufgaben ausführen, ohne auf den Abschluss des asynchronen Vorgangs warten zu müssen.
Asynchrone Programmierung kann die Leistung und Reaktionsfähigkeit von Anwendungen durch Delegierungs- und Rückruffunktionen verbessern. Es wird häufig in Szenarien verwendet, in denen zeitaufwändige Vorgänge ausgeführt, das Blockieren des Hauptthreads und die gleichzeitige Verarbeitung vermieden werden müssen.

3. Das Konzept und der grundlegende Einsatz von Veranstaltungen

3.1 Definition und Merkmale von Ereignissen

Ereignisse sind ein Mechanismus in der objektorientierten Programmierung zur Verarbeitung bestimmter Aktionen oder Zustandsänderungen, die an Objekten auftreten. Ereignisse können als eine besondere Art von Delegaten betrachtet werden, die eine lose gekoppelte Möglichkeit für die Kommunikation von Objekten bieten, indem sie Ereignisse definieren und auslösen.
Ereignisse weisen folgende Merkmale auf:

  1. Herausgeber- und Abonnentenmodell: Ereignisse haben normalerweise ein Objekt als Herausgeber, das das Ereignis auslöst, wenn bestimmte Bedingungen erfüllt sind. Andere Objekte können das Ereignis abonnieren und entsprechende Verarbeitungslogik bereitstellen, um auf das Eintreten des Ereignisses zu reagieren.
  2. Delegaten als Event-Handler-Typen: Ereignisse verwenden häufig Delegate-Typen, um Event-Handler zu definieren. Ein Delegat ist ein Typ, der auf eine Methode verweist, die als Parameter übergeben und aufgerufen werden kann, wenn ein Ereignis auftritt.
  3. Registrierung und Deregistrierung von Event-Handlern: Objekte, die Ereignisse abonnieren, können über +=den Operator ihre eigenen Methoden als Event-Handler registrieren. Wenn ein Ereignis auftritt, wird der registrierte Ereignishandler aufgerufen. Mithilfe -=des Operators kann die Registrierung eines Ereignishandlers aufgehoben werden, um keine Ereignisbenachrichtigungen mehr zu erhalten.
  4. Unterstützung mehrerer Ereignishandler: Ereignisse können mehrere Ereignishandler unterstützen, dh mehrere Methoden können gleichzeitig dasselbe Ereignis abonnieren. Wenn ein Ereignis auftritt, werden alle abonnierten Ereignishandler aufgerufen.
  5. Lose gekoppeltes Design: Der Ereignismechanismus realisiert eine lose Kopplung zwischen Objekten, und das Herausgeberobjekt muss die spezifische Implementierung des Abonnentenobjekts nicht verstehen und ist nicht direkt von dieser abhängig. Herausgeber müssen lediglich Ereignisse auslösen, und Abonnenten entscheiden, wie mit Ereignissen umgegangen wird.
3.2 Syntax und Deklaration von Ereignissen

In C# lautet die Syntax zum Deklarieren und Verwenden von Ereignissen wie folgt:

  1. Ereignisse definieren:
    public event EventHandler MyEvent;
    
    Der vorangehende Code definiert ein MyEventEreignis mit dem Namen „type“ EventHandler. EventHandlerIst ein vordefinierter Delegattyp, der normalerweise zur Verarbeitung von Ereignissen ohne Parameter verwendet wird.
  2. Event-Handler deklarieren:
    private void OnMyEvent(object sender, EventArgs e)
    {
        // 处理事件的逻辑代码
    }
    
    Der obige Code deklariert eine OnMyEventEvent-Handler-Methode mit dem Namen , die zwei Parameter akzeptiert: senderdas Publisher-Objekt, das das Ereignis darstellt, eund die Ereignisparameter. Je nach tatsächlichem Bedarf können Sie den Namen und die Parameter der Event-Handler-Methode anpassen.
  3. Registrieren Sie Event-Handler:
    MyEvent += OnMyEvent;
    
    Der vorangehende Code OnMyEventregistriert die Methode als MyEventHandler für das Ereignis. Die Methode wird aufgerufen , wenn MyEventdas Ereignis ausgelöst wird .OnMyEvent
  4. Event-Handler abmelden:
    MyEvent -= OnMyEvent;
    
    Der obige Code hebt die Registrierung OnMyEventder Methode aus MyEventder Handlerliste des Ereignisses auf und empfängt keine Ereignisbenachrichtigungen mehr.

Bitte beachten Sie, dass der obige Code nur ein Beispiel ist. Sie können ihn entsprechend Ihren tatsächlichen Anforderungen und Szenarien anpassen und erweitern. Gleichzeitig können Sie bei Bedarf auch benutzerdefinierte Ereignisparametertypen definieren, um dem Ereignisprozessor mehr Informationen zur Verfügung zu stellen.

3.3 Anmeldung und Auslösung von Ereignissen

In C# läuft das Abonnieren und Auslösen von Ereignissen wie folgt ab:

  1. Ereignisse definieren:

    public event EventHandler MyEvent;
    

    Definieren Sie ein MyEventEreignis mit dem Namen und verwenden Sie dabei EventHandlerden Delegatentyp als Ereignistyp.

  2. Definieren Sie Event-Handler:

    private void OnMyEvent(object sender, EventArgs e)
    {
        // 处理事件的逻辑代码
    }
    

    Definieren Sie eine OnMyEventals Ereignishandler benannte Methode, die zwei Parameter akzeptiert: senderdas Herausgeberobjekt, das das Ereignis darstellt, eund den Ereignisparameter.

  3. Veranstaltungen abonnieren:

    MyEvent += OnMyEvent;
    

    Die Event-Handler-Methode wird mithilfe +=des Operators OnMyEventfür das Ereignis abonniert MyEvent. Auf diese Weise MyEventwird beim Auslösen des Ereignisses die Event-Handler-Methode aufgerufen.

  4. auslösendes Ereignis:

    MyEvent?.Invoke(this, EventArgs.Empty);
    

    ?.InvokeEreignisse werden mithilfe der Syntax ausgelöst MyEvent. Dadurch werden wiederum alle Event-Handler-Methoden aufgerufen, die das Event abonniert haben. Parameter thisGibt das Herausgeberobjekt des Ereignisses und EventArgs.Emptydie Ereignisparameter an. Hier wird ein leeres Parameterobjekt verwendet.

  5. Von Veranstaltungen abmelden:

    MyEvent -= OnMyEvent;
    

    Verwenden Sie -=den Operator, um eine Event-Handler-Methode OnMyEventaus der Abonnementliste des Ereignisses MyEventabzumelden . Auf diese Weise MyEventwird die Event-Handler-Methode beim Auslösen des Ereignisses nicht mehr aufgerufen.

Die oben genannten Schritte sind die grundlegenden Schritte zum Abonnieren und Auslösen von Ereignissen. Sie können sie entsprechend den tatsächlichen Anforderungen und Szenarien anpassen und erweitern. Bitte beachten Sie, dass die Anmeldung und Auslösung von Ereignissen zum richtigen Zeitpunkt erfolgen sollte, um den korrekten Ereignisverarbeitungsprozess sicherzustellen.

4. Anwendungsszenarien von Ereignissen

4.1 Benutzerinteraktion in GUI-Anwendungen

In GUI-Anwendungen (Graphical User Interface) spielen Ereignisse eine wichtige Rolle bei der Handhabung von Benutzerinteraktionen. Im Folgenden sind einige häufige Anwendungsszenarien von Ereignissen in GUI-Anwendungen aufgeführt:

  1. Schaltflächenklickereignis: Ein Ereignis, das ausgelöst wird, wenn der Benutzer auf eine Schaltfläche auf der Benutzeroberfläche klickt, und verwandte Vorgänge können im Ereignishandler ausgeführt werden, z. B. das Absenden eines Formulars, das Öffnen eines neuen Fensters usw.
  2. Textfeld-Eingabeereignis: Ein Ereignis, das ausgelöst wird, wenn der Benutzer Inhalte in das Textfeld eingibt. Der Eingabetext kann über den Ereignishandler abgerufen und entsprechend verarbeitet werden, z. B. Eingabeüberprüfung, Echtzeitsuche usw.
  3. Menüauswahlereignis: Ein Ereignis, das ausgelöst wird, wenn der Benutzer eine Option im Menü auswählt, und entsprechende Vorgänge können im Ereignishandler ausgeführt werden, z. B. das Öffnen einer bestimmten Funktionsseite, das Ausführen eines bestimmten Befehls usw.
  4. Mausbewegungs- und Klickereignisse: Ereignisse, die ausgelöst werden, wenn der Benutzer die Maus auf der Benutzeroberfläche bewegt oder auf ein bestimmtes Element klickt, können gemäß der Logik des Ereignishandlers auf Mausoperationen reagieren, z. B. das Anzeigen von Eingabeaufforderungsinformationen, das Ziehen von Elementen usw.
  5. Ereignis zum Schließen des Fensters: Das Ereignis, das ausgelöst wird, wenn der Benutzer das Fenster schließt. Sie können verwandte Vorgänge im Ereignishandler ausführen, z. B. das Speichern von Daten, das Bereinigen von Ressourcen usw.

Durch die Verwendung von Ereignissen können GUI-Anwendungen eine Interaktion und Reaktion mit Benutzern erreichen und so ein benutzerfreundlicheres und flexibleres Benutzererlebnis bieten. Entwickler können verschiedene Benutzerinteraktionslogiken und -funktionen implementieren, indem sie entsprechende Ereignisse abonnieren und verarbeiten.

4.2 Nachrichtenbenachrichtigung und ereignisgesteuert

Ereignisse haben vielfältige Anwendungsszenarien in der Nachrichtenbenachrichtigung und der ereignisgesteuerten Programmierung. Im Folgenden finden Sie häufige Anwendungsfälle für Veranstaltungen in diesen Bereichen:

  1. Nachrichtenbenachrichtigung: Ereignisse können verwendet werden, um einen Nachrichtenbenachrichtigungsmechanismus zu implementieren. Wenn ein Ereignis auftritt, kann das System das entsprechende Ereignis auslösen und andere Module oder Objekte benachrichtigen, die das Ereignis abonniert haben. Dadurch kann eine Entkopplung und Nachrichtenübermittlung zwischen Modulen erreicht werden.
  2. Publish-Subscribe-Muster: Mithilfe von Ereignissen kann ein Publish-Subscribe-Muster implementiert werden, bei dem ein Objekt (Herausgeber) ein Ereignis auslöst und andere Objekte (Abonnenten) das Ereignis abonnieren und auf die entsprechende Verarbeitungslogik reagieren. Dieses Muster kommt in Szenarien wie verteilten Systemen und Nachrichtenwarteschlangen sehr häufig vor.
  3. Benutzerinteraktion in GUI-Anwendungen: In Anwendungen mit grafischer Benutzeroberfläche (GUI) ist ereignisgesteuerte Programmierung ein häufiges Muster. Wenn der Benutzer mit der Schnittstelle interagiert, werden Ereignisse verwendet, um entsprechende Antwortvorgänge auszulösen. Beispielsweise können das Klicken auf eine Schaltfläche, das Ziehen eines Elements, Tastatureingaben usw. entsprechende Ereignisse zur Verarbeitung auslösen.
  4. Asynchrone Programmierung: Ereignisse können zur Implementierung eines asynchronen Programmiermodells verwendet werden, bei dem ein Ereignis ausgelöst wird, wenn ein Vorgang abgeschlossen ist, um andere Teile zur Verarbeitung zu benachrichtigen. Dies ist nützlich, wenn große Datenmengen verarbeitet werden, Aufgaben mit langer Laufzeit ausgeführt werden oder eine Interaktion mit externen Ressourcen erforderlich ist.
  5. Erweiterung von Frameworks und Bibliotheken: Durch die Definition und Verwendung von Ereignissen können Entwickler Erweiterungspunkte für Frameworks und Bibliotheken bereitstellen, sodass andere Entwickler benutzerdefinierte Logik für bestimmte Ereignisse registrieren und so benutzerdefinierte und flexible Funktionserweiterungen realisieren können.

Durch den Einsatz von Ereignissen können eine lose Kopplung zwischen Modulen, flexible Skalierbarkeit und die Verwaltung asynchroner Vorgänge erreicht werden. Es handelt sich um einen leistungsstarken Mechanismus, der es verschiedenen Teilen eines Programms ermöglicht, effizient zusammenzuarbeiten und auf eine Weise zu interagieren, die auf Ereignisse reagiert.

5. Vergleich und Auswahl von Teilnehmern und Veranstaltungen

5.1 Der Unterschied zwischen Delegiertem und Ereignis

Delegaten und Ereignisse sind zwei wichtige Konzepte in der objektorientierten Programmierung, die zur Implementierung der Nachrichtenübermittlung und -verarbeitung zwischen Objekten verwendet werden. Obwohl sie in mancher Hinsicht ähnlich sind, gibt es einige Unterschiede in ihren Definitionen, Verwendungen und Zwecken.

  1. Definition und Syntax:
    • Ein Delegat ist ein Typ, der einen Verweis auf eine Methode kapselt. Es definiert die Signatur und den Rückgabetyp der Methode und kann zum Deklarieren von Variablen, Parametern und Rückgabetypen verwendet werden.
    • Ereignisse sind eine spezielle Art von Delegaten, die zum Definieren und Auslösen bestimmter Aktionen verwendet werden. Ereignisse werden eventmit dem Schlüsselwort deklariert und können nur in Klassen oder Strukturen definiert werden.
  2. Rolle und Zweck:
    • Delegaten werden verwendet, um Referenzen auf Methoden zu übergeben, wodurch es möglich wird, Methoden als Parameter an andere Methoden zu übergeben oder sie in Variablen zu speichern. Delegaten werden häufig in Szenarien wie Rückruffunktionen, Ereignisverarbeitung und asynchroner Programmierung verwendet.
    • Ereignisse sind eine spezielle Art von Delegaten, die zum Definieren und Auslösen bestimmter Aktionen oder Benachrichtigungen verwendet werden. Es ermöglicht einer Klasse oder Struktur, andere Objekte zu benachrichtigen, wenn ein bestimmtes Ereignis eintritt, und den entsprechenden Ereignishandler auszuführen.
  3. Abonnieren und auslösen:
    • Ein Delegat kann +=mithilfe des Operators mehrere Methoden abonnieren, sodass mehrere Methoden auf den Aufruf des Delegaten reagieren können. Wenn der Delegat aufgerufen wird, werden nacheinander die abonnierten Methoden aufgerufen.
    • Ein Ereignis ist eine spezielle Form der Delegation, die nur innerhalb der Klasse ausgelöst werden darf und externe Objekte nur auf das Eintreten von Ereignissen reagieren können, indem sie das Ereignis abonnieren.
  4. Sicherheit und Kapselung:
    • Ereignisse weisen eine höhere Sicherheit und Kapselung auf, da Ereignisse nur innerhalb der Klasse ausgelöst werden können und externe Objekte die Auslösung von Ereignissen nicht direkt aufrufen oder ändern können.
    • Ein Delegate ist relativ flexibler in der Verwendung, da er in einer Variablen gespeichert werden kann und es externen Objekten ermöglicht, den Delegaten direkt aufzurufen.
5.2 Wählen Sie den entsprechenden Delegierten und die entsprechende Veranstaltung aus

Bei der Auswahl geeigneter Teilnehmer und Veranstaltungen müssen spezifische Anwendungsszenarien und Anforderungen berücksichtigt werden. Hier sind ein paar Vorschläge:

  1. beauftragt:
    • Verwenden Sie Delegaten, um Methodenreferenzen zu übergeben, um Anforderungen wie Rückruffunktionen oder asynchrone Programmierung zu erfüllen.
    • Wenn Sie Methoden zwischen verschiedenen Objekten übergeben müssen und möchten, dass diese Objekte unabhängig voneinander Methodenaufrufe durchführen können, können Sie die Delegation verwenden.
  2. Ereignis:
    • Verwenden Sie Ereignisse, um bestimmte Aktionen oder Benachrichtigungen zu definieren und auszulösen, um eine Entkopplung und Nachrichtenübermittlung zwischen Objekten zu erreichen.
    • Wenn Sie eine bestimmte Aktion innerhalb der Klasse auslösen müssen und möchten, dass andere Objekte diese Aktion abonnieren und darauf reagieren, können Sie Ereignisse verwenden.
  3. Berücksichtigen Sie Sicherheit und Kapselung:
    • Wenn Sie das Auslösen und Ausführen von Ereignissen durch externe Objekte einschränken und den internen Status der Klasse schützen möchten, können Sie Ereignisse verwenden.
    • Wenn Sie die Referenz der Methode flexibel übergeben müssen und möchten, dass das externe Objekt den Delegaten direkt aufruft, können Sie den Delegaten verwenden.
  4. Berücksichtigen Sie Skalierbarkeit und Wiederverwendbarkeit:
    • Sie können Ereignisse verwenden, wenn Sie die gleiche Ereignisdefinition für mehrere Klassen verwenden möchten und jede Klasse unabhängig Ereignishandler hinzufügen und darauf reagieren soll.
    • Wenn Sie denselben Delegatentyp an mehreren Stellen wiederverwenden möchten und nicht auf interne Ereignisse einer bestimmten Klasse beschränkt sein möchten, können Sie sich für die Verwendung von Delegaten entscheiden.

Kurz gesagt eignen sich Delegaten für Szenarien wie die Übergabe von Methodenreferenzen, die Implementierung von Rückruffunktionen und die asynchrone Programmierung, während Ereignisse zum Definieren und Auslösen bestimmter Aktionen oder Benachrichtigungen sowie zum Erreichen einer Entkopplung zwischen Objekten geeignet sind. Wählen Sie entsprechend den Anforderungen der Anwendung den am besten geeigneten Mechanismus aus, um die Funktion zu realisieren und die Anforderungen zu erfüllen.

6. Best Practices und Vorsichtsmaßnahmen für Inbetriebnahme und Veranstaltungen

Hier sind einige Best Practices und Überlegungen bei der Verwendung von Delegaten und Ereignissen:

  1. Benennung von Delegierten und Ereignissen: Die Benennung sollte ihren Zweck und ihre Funktion genau widerspiegeln und den Namenskonventionen folgen, um die Lesbarkeit des Codes zu verbessern.
  2. Delegierte Lebenszyklusverwaltung: Bei der Verwendung von Delegaten müssen Sie sicherstellen, dass der delegierte Lebenszyklus korrekt verwaltet wird, um potenzielle Speicherlecks zu vermeiden. Verwenden Sie die entsprechenden Methoden, um delegierte Abonnements hinzuzufügen und zu entfernen.
  3. Zeitpunkt der Ereignisauslösung: Beim Entwerfen und Implementieren von Ereignissen müssen Sie den Zeitpunkt der Ereignisauslösung berücksichtigen, um sicherzustellen, dass Ereignisse zu einem geeigneten Zeitpunkt ausgelöst werden, um Anforderungen und Funktionen zu erfüllen.
  4. Sicherheit von Ereignishandlern: Wenn andere Objekte Ereignisse abonnieren und auf sie reagieren, muss die Sicherheit von Ereignishandlern gewährleistet werden, um mögliche Ausnahmen und Fehlerbedingungen zu behandeln und die Programmstabilität sicherzustellen.
  5. Dokumentation von Delegaten und Ereignissen: Stellen Sie im Code eine klare Dokumentation bereit, um den Zweck, die Verwendung und das erwartete Verhalten von Delegaten und Ereignissen zu erläutern und anderen Entwicklern zu helfen, sie zu verstehen und zu verwenden.
  6. Anwendbarkeit von Delegierten und Ereignissen: Bei der Entscheidung für den Einsatz von Delegierten und Ereignissen müssen spezifische Bedürfnisse und Szenarien berücksichtigt werden, um deren Anwendbarkeit und Rationalität sicherzustellen. Missbrauchen Sie Delegierte und Ereignisse nicht, sondern wählen Sie den geeigneten Programmiermechanismus entsprechend der tatsächlichen Situation aus.
  7. Klarheit und Wartbarkeit des Codes: Behalten Sie bei der Verwendung von Delegaten und Ereignissen die Klarheit und Wartbarkeit des Codes bei und befolgen Sie gute Codestil- und Designprinzipien, um die Lesbarkeit und Wartbarkeit des Codes zu verbessern.

7. Zusammenfassung

Delegaten und Ereignisse sind wichtige Konzepte in der objektorientierten Programmierung. Sie bieten Flexibilität und Erweiterbarkeit und ermöglichen es uns, entkoppelten und wiederverwendbaren Code zu erstellen. Delegierte ermöglichen es uns, Methoden als Parameter zu übergeben und zu speichern und sie bei Bedarf aufzurufen, was für die Implementierung von Rückruffunktionen und asynchroner Programmierung sehr nützlich ist. Ereignisse sind eine spezielle Form der Delegation, die bestimmte Aktionen abwickelt oder bestimmte Bedingungen auslöst. Ereignisse bieten eine lose gekoppelte Möglichkeit, Interaktionen zwischen Objekten zu benachrichtigen und darauf zu reagieren.
Bei der Verwendung von Delegaten und Ereignissen sollten wir Best Practices und Überlegungen befolgen, wie z. B. genaue Benennung, korrektes Lebenszyklusmanagement, rechtzeitiges Auslösen von Ereignissen, Umgang mit Sicherheit und Ausnahmen, Bereitstellung einer klaren Dokumentation usw. Die Auswahl des geeigneten Delegierten und der geeigneten Veranstaltung hängt von den spezifischen Bedürfnissen und Szenarien ab und stellt deren Anwendbarkeit und Rationalität sicher. Es ist sehr wichtig, den Code klar und wartbar zu halten. Ein guter Codierungsstil und gute Designprinzipien können die Lesbarkeit und Wartbarkeit des Codes verbessern.

Ich denke du magst

Origin blog.csdn.net/gangzhucoll/article/details/131750446
Empfohlen
Rangfolge