it-swarm-eu.dev

Einsatz von C # -Delegierten in der Praxis

Ich denke, dass ich C # -Delegierte konzeptionell verstehe, aber ich habe Schwierigkeiten, ein reales Beispiel zu finden, in dem sie nützlich wären. Können Sie einige Antworten geben, die detailliert beschreiben, wie C # -Delegierte in realen Anwendungen verwendet wurden und welche Probleme Sie damit umgehen konnten?.

16
AlexC

Der GUI-Code verwendet Delegaten, um Ereignisse wie Schaltflächenklicks und Fensterverschiebungen zu verarbeiten. Wenn Sie den Delegaten verwenden, können Sie eine Funktion aufrufen, wenn das Ereignis eintritt. Ein Beispiel wäre das Verknüpfen einer Funktion, die Daten speichert, mit einer Schaltfläche "Speichern" auf der Schnittstelle. Wenn auf die Schaltfläche geklickt wird, wird sie so eingerichtet, dass die Funktion zum Speichern von Daten ausgeführt wird. Dies ist bei der GUI-Programmierung hilfreich, da Ihr gesamtes Programm möglicherweise darauf wartet, dass der Benutzer etwas unternimmt, und Sie nicht wissen, 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.

Linq verwendet das Func<T> und Action<T> delegiert ü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.

12
Oded

Praktisch alles, was Observer Pattern verwendet, würde wahrscheinlich Delegaten implementieren.

Wenn Sie die Beschreibung lesen, werden Sie sich wahrscheinlich einige Szenarien vorstellen, in denen Sie sie verwenden würden. Die Behandlung von GUI-Ereignissen ist ein häufiges Beispiel.

12
whatsisname

Delegierte sind bei der asynchronen Programmierung sehr nützlich.

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.

9
James Love

Delegaten sind besonders nützlich als Lösung für das Loch im mittleren Muster . Im Wesentlichen gibt es viele Fälle, in denen Sie einen eindeutigen Befehlssatz in einen gemeinsamen Anweisungssatz einbinden möchten. Es ist besonders schwierig, wenn die Anweisungen vor und nach dem eindeutigen Bit den Status teilen müssen. Mit Delegaten können Sie einfach einen Delegaten 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.

9
Scott Whitlock

In den "alten Tagen" von Nicht-OOP-Sprachen wie Fortran und C war es unglaublich nützlich, eine Unterroutine ein Argument empfangen zu lassen, das ein Zeiger auf eine Funktion war. Beispielsweise funktioniert die Funktion qsort 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 frühen Tagen 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 diesem interagieren konnte.

Dieselbe Notwendigkeit 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 Sie übergeben müssen Ein Delegierter ist also genau das und lässt zu, dass dieses gute alte Muster weiterhin verwendet wird.

5
Mike Dunlavey

Hier ist ein einfaches Beispiel, das zeigt, wie nützlich Delegaten beim Erstellen von einfachem Code sein können, der dem Prinzip DRY] folgt. Außerdem können Sie Code extrem nahe an dem Ort halten, an dem er benötigt wird.

Action<Button, Action<Button>> prepareButton = 
    (btn, nxt) => { 
        btn.Height = 32;
        btn.Width= 64;
        nxt(btn);
    };

prepareButton(myBtn1, btn => btn.Text = "A");
prepareButton(myBtn2, btn => btn.Text = "B");
prepareButton(myBtn3, btn => btn.Text = "C");

Hier ist ein Beispiel aus der Praxis für den Vorteil, den Delegierte bieten.

protected override void PageInitialize()
{
    const string selectCodeFormat = "javascript:selectCode('{0}', '{1}');";
    const string onClick = "return toggleElement(this);";

    Func<HtmlGenericControl> getElement = null;
    Action<HtmlGenericControl> setElement = null, addChild = null;
    HtmlGenericControl level1Element = null, level2Element = null, level3Element = null, level4Element = null;
    string className = null, code = null, description = null;           

    using (var records = Core.Database.ExecuteRecords("code.SocCodeTree"))
    {
        while (records.Read())
        {
            code = records.GetString("Code");
            description = records.GetString("Description"); 

            if (records.GetString("Level4") != "")
            {
                className = "Level4";
                setElement = e => level4Element = e;
                getElement = () => level4Element;
                addChild = e => level3Element.Controls.Add(e);
            }
            else if (records.GetString("Level3") != "")
            {
                className = "Level3";
                setElement = e => level3Element = e;
                getElement = () => level3Element;
                addChild = e => level2Element.Controls.Add(e);
            }
            else if (records.GetString("Level2") != "")
            {
                className = "Level2";
                setElement = e => level2Element = e;
                getElement = () => level2Element;
                addChild = e => level1Element.Controls.Add(e);
            }
            else
            {
                className = "Level1";
                setElement = e => level1Element = e;
                getElement = () => level1Element;
                addChild = e => Root.Controls.Add(e);
            }

            var child = new HtmlGenericControl("li");
            child.Attributes["class"] = className;
            var span = new HtmlGenericControl("span") { 
                InnerText = code + " - " + description + " - " 
            };
            span.Attributes["onclick"] = onClick;
            child.Controls.Add(span);
            var a = new HtmlAnchor() { 
                InnerText = "Select", 
                HRef = string.Format(selectCodeFormat, code, description) 
            };
            child.Controls.Add(a);
            setElement(new HtmlGenericControl("ul"));
            child.Controls.Add(getElement());
            addChild(child);    
        }
    }
}
3
ChaosPandion

Meine erste Begegnung mit Delegierten bestand darin, nach einer Programmaktualisierung (Windows Forms C # 3.5) zu suchen, indem ich eine Datei von meiner Website herunterlud. Um jedoch zu vermeiden, dass die Aktualisierung der Aktualisierung das gesamte Programm sperrte, verwendete ich einen Delegaten und einen Thread, um dies asynchron durchzuführen.

2
Ken

Ich habe interessante Implementierungen des Strategiemusters gesehen, bei denen Delegierte effektiv eingesetzt werden. (dh die Strategie ist ein Delegierter)

Ich suchte nach einer Pfadfindung, bei der der Algorithmus zum Auffinden des Pfads ein Delegat war, der zur Laufzeit (neu) zugewiesen werden konnte, damit verschiedene Algorithmen verwendet werden konnten (BFS vs A * usw.).

1
Steven Evers

Viele der klassischen GoF-Muster können mit Delegaten implementiert werden: Beispielsweise können Befehlsmuster, Besuchermuster, Strategiemuster, Factory-Muster und Beobachtermuster häufig mit einem einfachen Delegaten implementiert werden. Manchmal ist eine Klasse besser (z. B. wenn ein Befehl einen Namen benötigt oder ein Strategieobjekt serialisiert werden muss), in den meisten Fällen jedoch Action<...> oder Func<...> ist viel eleganter als das Erstellen einer dedizierten Ein-Methoden-Schnittstelle.

1
nikie