Ich denke, dass ich C # -Delegierte konzeptionell verstehe, aber ich habe Mühe, ein reales Beispiel zu finden, in dem sie nützlich wären. Können Sie einige Antworten geben, in denen detailliert beschrieben wird, wie C # -Delegierte in realen Anwendungen verwendet wurden und welche Probleme Sie damit umgehen konnten?
16
Antworten:
GUI-Code verwendet Delegaten, um Ereignisse wie Tastenklicks und Fensterverschiebungen zu verarbeiten. Die Verwendung des Delegaten ermöglicht es Ihnen, eine Funktion aufzurufen, wenn das Ereignis eintritt. Ein Beispiel wäre die Verknüpfung einer Funktion, die Daten speichert, mit einer Schaltfläche "Speichern" auf der Oberfläche. Wenn Sie auf die Schaltfläche klicken, wird die Funktion zum Speichern von Daten ausgeführt. Dies ist bei der GUI-Programmierung hilfreich, da Ihr gesamtes Programm möglicherweise darauf wartet, dass der Benutzer etwas unternimmt, und Sie nicht wissen können, was er zuerst tun wird. Durch die Verwendung von Delegaten kann die Funktionalität Ihres Programms so mit der Benutzeroberfläche verbunden werden, dass der Benutzer die gewünschten Aktionen ausführen kann.
quelle
Linq verwendet das
Func<T>
undAction<T>
überall als Parameter.Mit diesen können Sie Lambda-Ausdrücke als Parameter verwenden und die Aktion definieren, die als Teil der Parameterliste ausgeführt werden soll.
quelle
Praktisch alles, was das Beobachtermuster verwendet, würde wahrscheinlich Delegierte implementieren.
Lesen Sie die Beschreibung und stellen Sie sich wahrscheinlich einige Szenarien vor, in denen Sie sie verwenden würden. GUI-Ereignisbehandlung ist ein häufiges Beispiel.
quelle
Die Delegierten sind bei der asynchronen Programmierung von verdammtem Nutzen.
Sie haben eine Klasse, die asynchron arbeitet und einen Rückruf hat. Sie können die Delegate-Methode beim Rückruf aufrufen lassen - und Ihre Klassenimplementierung führt die in Ihrer Delegate-Methode beschriebene Logik aus.
quelle
Delegierte sind besonders nützlich als Lösung für das Loch im mittleren Muster . Grundsätzlich gibt es viele Fälle, in denen Sie einen eindeutigen Befehlssatz in einen gemeinsamen Befehlssatz einschließen möchten. Es ist besonders schwierig, wenn die Anweisungen vor und nach dem eindeutigen Bit den Status teilen müssen. Bei Delegierten können Sie einen Delegierten einfach an eine Funktion übergeben. Die Funktion führt das Vorher-Bit aus, führt den Delegaten aus und führt dann das Nachher-Bit aus.
quelle
In den "alten Tagen" von Nicht-OOP-Sprachen wie Fortran und C war es unglaublich nützlich, dass ein Unterprogramm ein Argument erhielt, das auf eine Funktion zeigte. Beispielsweise arbeitet die
qsort
Funktion mit einer vom Benutzer bereitgestellten Vergleichsfunktion. Es gibt zahlreiche Unterprogramme zum Lösen gewöhnlicher Differentialgleichungen oder zum Optimieren von Funktionen, und alle verwenden Funktionszeiger als Argumente.In Fenstersystemen folgen alle Arten von Rückrufen demselben Muster.
In Lisp gab es schon in den Anfängen ein sogenanntes "funktionales Argument" oder FUNARG, das nicht nur eine Funktion war, sondern auch einen Speicherkontext enthielt, in dem es sich an einen Teil der Außenwelt erinnern und mit diesen interagieren konnte.
Dieselbe Anforderung besteht in OOP-Sprachen, außer wenn Sie die Adresse einer Funktion übergeben, müssen Sie auch die Adresse des Objekts übergeben, für das die Funktion eine Methode ist. Das sind zwei Dinge, die man bestehen muss. Ein Delegierter ist genau das und lässt zu, dass dieses gute alte Muster weiterhin verwendet wird.
quelle
Hier ist ein einfaches Beispiel, das zeigt, wie nützlich Delegaten beim Erstellen von einfachem Code sein können, der dem DRY-Prinzip folgt. Sie können den Code auch extrem nahe an der Stelle speichern, an der er benötigt wird.
Hier ist ein reales Beispiel für den Vorteil, den Delegierte bieten.
quelle
Meine erste Begegnung mit Delegierten bestand darin, durch Herunterladen einer Datei von meiner Website nach Programmaktualisierungen zu suchen (Windows Forms C # 3.5). Um jedoch zu vermeiden, dass die Überprüfung des Updates das gesamte Programm sperrte, verwendete ich einen Delegaten und einen Thread, um dies asynchron zu tun.
quelle
Ich habe interessante Implementierungen des Strategiemusters gesehen, bei denen die Delegierten effektiv eingesetzt werden. (dh die Strategie ist ein Delegierter)
Die eine, die ich suchte, war für die Pfadfindung, wo der Algorithmus zum Finden des Pfades ein Delegat war, dem zur Laufzeit (neu) zugewiesen werden konnte, so dass verschiedene Algorithmen verwendet werden konnten (BFS vs A * usw.).
quelle
Viele der klassischen GoF-Muster können mit Delegierten implementiert werden: Beispielsweise können Befehlsmuster, Besuchermuster, Strategiemuster, Factory-Muster und Beobachtermuster häufig mit einem einfachen Delegierten implementiert werden. Manchmal ist eine Klasse besser (z. B. wenn ein Befehl einen Namen benötigt oder ein Strategieobjekt serialisiert werden muss), aber in den meisten Fällen ist die Verwendung von
Action<...>
oderFunc<...>
viel eleganter als die Erstellung einer dedizierten Ein-Methoden-Schnittstelle.quelle