Was ist ein Delegierter? [geschlossen]

152

Ich bin verwirrt, welche Rolle ein Delegierter tatsächlich spielt.

Diese Frage wurde mir in meinen Interviews oft gestellt, aber ich glaube nicht, dass die Interviewer mit meiner Antwort zufrieden waren.

Kann mir jemand die beste Definition in einem Satz anhand eines praktischen Beispiels nennen?

Naveed
quelle
21
Was haben Sie aus Neugier geantwortet, damit wir Ihnen sagen können, wie Sie es korrigieren können?
Anthony Forloney
6
Ich finde es interessant, dass diese Frage geschlossen wurde, aber 126 positive Stimmen hat und 65 Personen sie als Favorit markiert haben. Selbst wenn es zu breit ist, scheint es immer noch eine sehr gute Frage zu sein.
Rich

Antworten:

171

Ich stelle mir einen Delegierten gerne als "Zeiger auf eine Funktion" vor. Dies geht auf C Tage zurück, aber die Idee hält immer noch.

Die Idee ist, dass Sie in der Lage sein müssen, einen Code aufzurufen, aber dieser Code, den Sie aufrufen möchten, ist erst zur Laufzeit bekannt. Sie verwenden also einen "Delegaten" für diesen Zweck. Delegierte sind nützlich für Dinge wie Ereignishandler und dergleichen, bei denen Sie beispielsweise verschiedene Dinge basierend auf verschiedenen Ereignissen ausführen.

Hier ist eine Referenz für C #, die Sie sich ansehen können:

Nehmen wir zum Beispiel in C # an, wir hatten eine Berechnung, die wir durchführen wollten, und wir wollten eine andere Berechnungsmethode verwenden, die wir erst zur Laufzeit kennen. Wir könnten also ein paar Berechnungsmethoden wie diese haben:

public static double CalcTotalMethod1(double amt)
{
    return amt * .014;
}

public static double CalcTotalMethod2(double amt)
{
    return amt * .056 + 42.43;
}

Wir könnten eine Delegatensignatur wie folgt deklarieren:

public delegate double calcTotalDelegate(double amt);

Und dann könnten wir eine Methode deklarieren, die den Delegaten als Parameter wie diesen verwendet:

public static double CalcMyTotal(double amt, calcTotalDelegate calcTotal)
{
    return calcTotal(amt);
}

Und wir könnten die CalcMyTotalMethode aufrufen, die in der Delegatenmethode übergeben wird, die wir verwenden wollten.

double tot1 = CalcMyTotal(100.34, CalcTotalMethod1);
double tot2 = CalcMyTotal(100.34, CalcTotalMethod2);
Console.WriteLine(tot1);
Console.WriteLine(tot2);
dcp
quelle
19
+1 für die Anspielung auf den einfachen, aber effektiven Funktionszeiger in C.
Aiden Bell
3
Eine Frage bezog sich auf Ihre Antwort. Wie unterscheidet es sich wirklich vom normalen Aufrufen einer Funktion? Nur deswegen ist es zur Laufzeit nicht bekannt?
Naveed
1
@NAVEED - siehe meine letzte Bearbeitung, ich habe ein Beispiel beigefügt. Was den eigentlichen Methodenaufruf betrifft, sieht er in meinem obigen Beispiel nicht anders aus als ein normaler Methodenaufruf (das calcTotal (amt) ruft den Delegaten auf), aber die Macht der Delegaten besteht darin, dass Sie sie als Parameter verwenden können. usw., wenn eine Methode ein anderes Verhalten aufweisen soll. Es gibt viele andere Dinge, für die Sie sie auch verwenden können. Dies ist nur ein einfaches Beispiel. Hoffentlich hilft das.
DCP
Es ist zur Laufzeit nicht bekannt und eher eine gebundene Funktion als eine freie Funktion. Wenn Sie einem FooDelegaten eine nicht statische Methode zuweisen, wird this.Foo()eher eine statische Funktion aufgerufen, als dies ein Funktionszeiger tun würde (in C haben Sie häufig einen zusätzlichen void*Parameter für Übergabe thisan den Funktionszeiger)
Pete Kirkham
1
+1 für das schnelle und effektive Beispiel zum Erstellen von Ähnlichkeiten mit Funktionszeigern in C / C ++. Sehr geschätzt!
G21
19

Ein Delegat ist einfach ein Funktionszeiger.
Geben Sie einfach die Methode an, mit der Sie Ihren Delegaten ausführen möchten. später im Code können Sie diese Methode über Invoke aufrufen.

etwas Code zu demonstrieren (schrieb dies aus dem Speicher, so dass die Syntax möglicherweise deaktiviert ist)

delegate void delMyDelegate(object o);

private void MethodToExecute1(object o)
{
    // do something with object
}

private void MethodToExecute2(object o)
{
    // do something else with object
}

private void DoSomethingToList(delMyDelegate methodToRun)
{
    foreach(object o in myList)
        methodToRun.Invoke(o);
}

public void ApplyMethodsToList()
{
    DoSomethingToList(MethodToExecute1);
    DoSomethingToList(MethodToExecute2);
}
Mladen Prajdic
quelle
16

Von hier genommen

F Was sind Delegierte?
A Wenn ein Objekt eine Anforderung empfängt, kann das Objekt entweder die Anforderung selbst bearbeiten oder die Anforderung an ein zweites Objekt weiterleiten, um die Arbeit auszuführen. Wenn das Objekt beschließt, die Anforderung weiterzuleiten, geben Sie an, dass das Objekt die Verantwortung für die Bearbeitung der Anforderung an das zweite Objekt weitergeleitet hat.

Oder als einfaches Pseudobeispiel: Etwas sendet eine Anfrage an object1. object1 leitet dann die Anfrage und sich selbst an object2 - den Delegaten - weiter. object2 verarbeitet die Anfrage und erledigt einige Arbeiten. (Hinweis: Link oben gibt gute Beispiele)

Anthony Forloney
quelle
Das im obigen Link angegebene Beispiel gibt die Delegierung nicht korrekt an.
Hardik9850
4

Stellen Sie sich Delegate als eine vereinfachte Implementierung des Befehlsmusters vor.

Vitaliy Liptchinsky
quelle
4

Ein Delegat ist ein Objekt, das auf eine Methode verweisen kann. Wenn wir also einen Delegaten erstellen, erstellen wir ein Objekt, das einen Verweis auf eine Methode enthalten kann. Darüber hinaus kann die Methode über diese Referenz aufgerufen werden. Somit kann ein Delegat die Methode aufrufen, auf die er sich bezieht. Der Hauptvorteil eines Delegaten besteht darin, dass wir einen Aufruf einer Methode angeben können, die tatsächlich aufgerufene Methode jedoch zur Laufzeit und nicht zur Kompilierungszeit festgelegt wird.

Einfacher Delegierter

Declaration of delegate:
delegate-modifier delegate return-type delegate-name(parameters)
Implementation of delegate:
Delegate-name delegate-object=new Delegate-name(method of class)

http://knowpacific.wordpress.com/2012/01/26/delegate/

Sandeep Shekhawat
quelle
2

Hier werde ich Delegaten, Multicast-Delegaten und ihre Verwendung erläutern. Delegat ist ein Typ, der die Methodenreferenz (en) in einem Objekt enthält. Es wird auch als typsicherer Funktionszeiger bezeichnet. Wir können sagen, ein Delegat ist ein Typ, der eine Methodensignatur definiert.

Wenn Sie einen Delegaten instanziieren, können Sie seine Instanz jeder Methode mit einer kompatiblen Signatur zuordnen. Sie können die Methode über die Delegateninstanz aufrufen (oder aufrufen). Delegaten werden verwendet, um Methoden als Argumente an andere Methoden zu übergeben. Ereignishandler sind nichts anderes als Methoden, die über Delegaten aufgerufen werden. Die Verwendung von Delegaten bietet folgende Vorteile: Kapselung des Methodenaufrufs vom Aufrufer Die effektive Verwendung von Delegaten verbessert die Leistung der Anwendung. Wird zum asynchronen Aufrufen einer Methode verwendet. Es gibt einige Eigenschaften von Delegierten

Delegates are like C++ function pointers but are type safe.
Delegates allow methods to be passed as parameters.
Delegates can be used to define callback methods.
Delegates can be chained together; for example, multiple methods can be called on a single event.
Methods do not have to match the delegate signature exactly.

öffentlicher Delegat type_of_delegate delegate_name () // Deklaration

You can use delegates without parameters or with parameter list
If you are referring to the method with some data type then the delegate which you are declaring should be in the same format. This is why it is referred to as type safe function pointer. Here I am giving an example with String.

Das folgende Beispiel zeigt eine Delegierungsoperation:

    namespace MyDelegate
    {
        class Program
        {
            private delegate void Show(string s);


            // Create a method for a delegate.
            public static void MyDelegateMethod(string me

ssage)
        {
            System.Console.WriteLine(message);
        }

        static void Main(string[] args)
        {
            Show p = MyDelegateMethod;
            p("My Delegate");
            p.Invoke("My Delegate");
            System.Console.ReadLine();
        }
    }
}

Was ist ein Multicast-Delegierter?

Es ist ein Delegat, der die Referenz von mehr als einer Methode enthält. Multicast-Delegaten dürfen nur Methoden enthalten, die void zurückgeben, andernfalls gibt es eine Laufzeitausnahme.

 delegate void MyMulticastDelegate(int i, string s);
 Class Class2
 {
  static void MyFirstDelegateMethod(int i, string s)
  {
    Console.WriteLine("My First Method");
  }

  static void MySecondDelegateMethod(int i, string s)
  {
    Console.WriteLine("My Second Method");
  }

  static void Main(string[] args)
  {
    MyMulticastDelegate Method= new MyMulticastDelegate(MyFirstDelegateMethod);
    Method+= new MyMulticastDelegate (MySecondDelegateMethod);
    Method(1,"Hi");             // Calling 2 Methodscalled
    Method-= new MyMulticastDelegate (MyFirstDelegateMethod);
    Method(2,"Hi");             //Only 2nd Method calling
  }
}

Hier wird Delegate mit dem Operator + = hinzugefügt und mit dem Operator - = entfernt.

Delegatentypen werden von der Delegate-Klasse in .NET Framework abgeleitet. Delegatentypen sind versiegelt - sie können nicht abgeleitet werden. Da der instanziierte Delegat ein Objekt ist, kann er als Parameter übergeben oder einer Eigenschaft zugewiesen werden. Auf diese Weise kann eine Methode einen Delegaten als Parameter akzeptieren und den Delegaten zu einem späteren Zeitpunkt aufrufen. Dies wird als asynchroner Rückruf bezeichnet.

Jom George
quelle
1

Eine gute Erklärung und praktische Implementierung des Delegate-Musters finden Sie in den Google Collections Forwarding Classes (auch im Decorator-Muster).

Carl
quelle
1

In der Ereigniskommunikation weiß der Absender nicht, welches Objekt das Ereignis behandelt. Delegate ist ein Typ, der die Referenz der Methode enthält. Der Delegat hat eine Signatur und verweist auf eine Methode, die mit seiner Signatur übereinstimmt, sodass der Delegat wie ein typsicherer Funktionszeiger ist.

button1.Click + = neuer System.EventHandler (button1_Click) System.EventHandler wird hier als Delegat deklariert. In .net Events wird am Konzept des Delegaten gearbeitet (wie Button Click).

Delegate wird verwendet, wenn Sie nicht wissen, welchen Code Sie zur Laufzeit aufrufen sollen. Zu diesem Zeitpunkt wird Delegate zum Behandeln von Ereignissen verwendet

http://msdn.microsoft.com/en-us/library/ms173171(v=vs.80).aspx

Yogesh
quelle
1

Ein Delegatenobjekt ist ein Objekt, das ein anderes Objekt konsultiert, wenn in diesem Objekt etwas passiert. Zum Beispiel ist Ihr Reparaturmann Ihr Stellvertreter, wenn etwas mit Ihrem Auto passiert. Sie gehen zu Ihrem Reparaturmann und bitten ihn, das Auto für Sie zu reparieren (obwohl einige es vorziehen, das Auto selbst zu reparieren. In diesem Fall sind sie ihr eigener Delegierter für ihr Auto).


quelle
1

Ein Delegat ist ein Objekt, das einen Zeiger auf eine Funktion darstellt. Es ist jedoch kein gewöhnlicher Funktionszeiger, da es:

1) Ist objektorientiert

2) Ist typsicher, dh es kann nur auf eine Methode verweisen und Sie können die Rohspeicheradresse, auf die sie verweist, nicht lesen

3) Ist stark getippt. Es kann nur auf Methoden verweisen, die mit den Signaturen übereinstimmen.

4) Kann auf mehr als eine Methode gleichzeitig verweisen.

Wasserkühler v2
quelle
1

Delegaten werden hauptsächlich bei Veranstaltungen verwendet.

Die Notwendigkeit ist:

Sie möchten zum Zeitpunkt der Ausführung des Programms keinen Code ausführen. Nach dem Ausführen des Programms möchten Sie diesen Code ausführen, wenn ein Ereignis auftritt.

Beispiel:

  1. Konsolenanwendung - Code kann nur zum Zeitpunkt der Ausführung des Programms ausgeführt werden. (Geschrieben in der Hauptmethode)
  2. Windows-Anwendung (Benutzeroberflächenprogrammierung) - Code kann ausgeführt werden, wenn Sie nach dem Ausführen des Programms auf die Schaltfläche klicken.

Dies ist, was sie sagen, Sie wissen nicht, welche Methode beim Kompilieren aufgerufen wird. Sie wissen es nur zur Laufzeit, wenn Sie auf die Schaltfläche klicken.

Ohne Delegierte ist keine Benutzeroberflächenprogrammierung möglich. Weil Sie Code ausführen, wenn der Benutzer Ereignisse ausführt, indem er auf die Schaltfläche klickt, ein Textfeld eingibt, ein Dropdown-Listenelement auswählt usw.

Shathar Khan
quelle
0

Ein Delegat ist etwas, an das eine Aufgabe delegiert wird. Der Hauptzweck der Delegierung besteht darin, Code zu entkoppeln und eine größere Flexibilität und Wiederverwendung zu ermöglichen.

Bei der Programmierung und insbesondere bei der objektorientierten Programmierung bedeutet dies, dass eine Methode, wenn sie zum Ausführen einer Arbeit aufgerufen wird, die Arbeit an die Methode eines anderen Objekts weitergibt, auf das sie verweist. Die Referenz könnte auf jedes gewünschte Objekt verweisen, solange das Objekt einem vordefinierten Satz von Methoden entspricht. Wir nennen es "Programmierung auf eine Schnittstelle" (im Gegensatz zur Programmierung auf eine konkrete Klassenimplementierung). Eine Schnittstelle ist im Grunde eine generische Vorlage und hat keine Implementierung. es bedeutet einfach ein Rezept, eine Reihe von Methoden, Vorbedingungen und Nachbedingungen (Regeln).

Einfaches Beispiel:

SomeInterface
{
   public void doSomething();
}


SomeImplementation implements SomeInterface
{
   public void doSomething()
   {
      System.err.println("Was it good for you?");
   }

}


SomeCaller
{
   public void doIt(SomeInterface someInterface)
   {
      someInterface.doSomething();
   }
}

Jetzt sehen Sie, dass ich jederzeit jede gewünschte Implementierung verwenden kann, ohne den Code in SomeCaller zu ändern, da der übergebene Typ doIt()nicht konkret, sondern abstrakt ist, da es sich um eine Schnittstelle handelt. In der Java-Welt wird dies häufig in dem Dienstparadigma ausgedrückt, in dem Sie einen Dienst aufrufen (ein Objekt, das sich selbst als Dienst über eine bestimmte Schnittstelle bewirbt), und der Dienst dann Delegierte aufruft, um ihn bei seiner Arbeit zu unterstützen. Die Methoden des Dienstes werden als grobkörnige Aufgaben (makePayment (), createNewUser () usw.) bezeichnet, während intern viele Aufgaben ausgeführt werden, wenn die Delegierung nicht vollständig funktioniert, wobei die Delegiertypen Schnittstellen anstelle der konkreten Implementierungen sind.

SomeService
{
    SomeInterface someImplementation = ... // assign here
    SomeOtherInterface someOtherImplementation = ... // okay, let's add a second

    public void doSomeWork()
    {
         someImplementation.doSomething();
         someOtherImplementation.doSomethingElse();
    }
}

(NB: Wie eine Implementierung zugewiesen wird, geht über den Rahmen dieses Threads hinaus. Lookup-Inversion von Steuerung und Abhängigkeitsinjektion.)

Aquarelle
quelle
-2

Ein Delegat ist zwar kein "Funktionszeiger", sieht aber möglicherweise so aus, als wäre dies eine dynamische Sprache wie PHP:



$func = 'foo';
$func();

function foo() {
    print 'foo';
}

oder in JavaScript könnten Sie etwas tun wie:


var func = function(){ alert('foo!'); }
func();

mmattax
quelle
2
Dies ist kein Beispiel für eine Delegierung. In Ihrem Beispiel verwenden Sie eine sogenannte Variablenfunktion, die im Grunde nach einer Funktion sucht, die denselben Namen hat wie die Zeichenfolge, auf die sich eine Variable bezieht. Siehe variable Funktionen: php.net/manual/en/functions.variable-functions.php
Aquarelle