Cos'è il delegato? [chiuso]


152

Sono confuso che qual è l'effettivo ruolo di un delegato?

Mi è stata posta questa domanda molte volte nelle mie interviste, ma non credo che gli intervistatori fossero soddisfatti della mia risposta.

Qualcuno può dirmi la migliore definizione, in una frase, con un esempio pratico?


21
per curiosità, cosa hai risposto in modo che possiamo dirti come puoi correggerlo?
Anthony Forloney,

6
Trovo interessante che questa domanda sia stata chiusa, ma ha 126 voti positivi e 65 persone lo hanno contrassegnato come preferito. Sembra che anche se è troppo ampio, è comunque un'ottima domanda.
Ricco

Risposte:


171

Mi piace pensare a un delegato come "un puntatore a una funzione". Questo risale ai giorni C, ma l'idea è ancora valida.

L'idea è che devi essere in grado di invocare un pezzo di codice, ma quel pezzo di codice che invocherai non è noto fino al runtime. Quindi usi un "delegato" per quello scopo. I delegati sono utili per cose come i gestori di eventi e simili, dove ad esempio fai cose diverse in base a eventi diversi.

Ecco un riferimento per C # che puoi vedere:

In C #, ad esempio, supponiamo di avere un calcolo che volevamo fare e volevamo usare un metodo di calcolo diverso che non conosciamo fino al runtime. Quindi potremmo avere un paio di metodi di calcolo come questo:

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

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

Potremmo dichiarare una firma delegata come questa:

public delegate double calcTotalDelegate(double amt);

E quindi potremmo dichiarare un metodo che prende il delegato come parametro come questo:

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

E potremmo chiamare il CalcMyTotalmetodo passando nel metodo delegato che volevamo usare.

double tot1 = CalcMyTotal(100.34, CalcTotalMethod1);
double tot2 = CalcMyTotal(100.34, CalcTotalMethod2);
Console.WriteLine(tot1);
Console.WriteLine(tot2);

19
+1 per annuire al semplice ma efficace puntatore a funzione in C.
Aiden Bell,

3
Una domanda relativa alla tua risposta. In che modo è veramente diverso dal chiamare una funzione in modo normale? Solo per questo non è noto in fase di esecuzione?
Naveed,

1
@NAVEED - fare riferimento alla mia ultima modifica, ho incluso un esempio. Per quanto riguarda l'effettiva chiamata del metodo, non sembra affatto diversa da una normale chiamata del metodo nel mio esempio sopra (il calcTotal (amt) sta chiamando il delegato), ma il potere dei delegati è che puoi usarli come parametri, ecc. quando si desidera che un metodo sia in grado di avere un comportamento diverso. Ci sono molte altre cose per cui puoi usarle, questo è solo un semplice esempio. Spero che aiuti.
dcp,

Non è noto in fase di runtime ed è una funzione associata piuttosto che una funzione libera: l'assegnazione di un metodo non statico Fooa un delegato chiamerà this.Foo()anziché una funzione statica come farebbe un puntatore a funzione (in C, spesso hai un void*parametro aggiuntivo per passare thisal puntatore a funzione)
Pete Kirkham,

1
+1 per l'esempio rapido ed efficace che stabilisce somiglianze con i puntatori a funzione in C / C ++. Molto apprezzato!
G21

19

un delegato è semplicemente un puntatore a funzione.
ti basta semplicemente assegnare il metodo che desideri eseguire il tuo delegato. poi più avanti nel codice puoi chiamare quel metodo tramite Invoke.

un po 'di codice per dimostrare (scritto dalla memoria in modo che la sintassi possa essere disattivata)

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);
}

16

Tratto da qui

D Cosa sono i delegati?
A Quando un oggetto riceve una richiesta, l'oggetto può gestire la richiesta stessa o passare la richiesta a un secondo oggetto per eseguire il lavoro. Se l'oggetto decide di inoltrare la richiesta, si afferma che l'oggetto ha inoltrato la responsabilità della gestione della richiesta al secondo oggetto.

Oppure, come semplice pseudo esempio: qualcosa invia una richiesta a object1. object1 quindi inoltra la richiesta e se stesso a object2 - il delegato. object2 elabora la richiesta e funziona. (nota: il link sopra fornisce buoni esempi)


L'esempio fornito nel link sopra non indica correttamente la delega.
Hardik9850,


4

Un delegato è un oggetto che può fare riferimento a un metodo. Pertanto, quando creiamo un delegato, stiamo creando un oggetto che può contenere un riferimento a un metodo. Inoltre, il metodo può essere chiamato tramite questo riferimento. Pertanto, un delegato può invocare il metodo a cui si riferisce. Il vantaggio principale di un delegato è che ci consente di specificare una chiamata a un metodo, ma il metodo effettivamente richiamato viene determinato in fase di esecuzione, non in fase di compilazione.

Delegato semplice

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/


2

Qui spiegherò i delegati, i delegati multicast e il loro utilizzo. Il delegato è un tipo che contiene il riferimento ai metodi in un oggetto. Viene anche indicato come puntatore a funzione sicura di tipo. Possiamo dire che un delegato è un tipo che definisce una firma del metodo.

Quando si crea un'istanza di un delegato, è possibile associare la sua istanza a qualsiasi metodo con una firma compatibile. È possibile richiamare (o chiamare) il metodo tramite l'istanza delegata. I delegati vengono utilizzati per passare metodi come argomenti ad altri metodi. I gestori di eventi non sono altro che metodi che vengono invocati tramite delegati. I vantaggi dell'utilizzo dei delegati sono: Incapsulare la chiamata del metodo dal chiamante L'uso efficace del delegato migliora le prestazioni dell'applicazione Utilizzato per chiamare un metodo in modo asincrono. Ci sono alcune proprietà dei delegati

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.

delegato pubblico type_of_delegate delegate_name () // Dichiarazione

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.

L'esempio seguente mostra un'operazione delegata:

    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();
        }
    }
}

Che cos'è il delegato multicast?

È un delegato che detiene il riferimento di più di un metodo. I delegati multicast devono contenere solo metodi che restituiscono null, altrimenti esiste un'eccezione di runtime.

 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
  }
}

Qui il delegato viene aggiunto usando l'operatore + = e rimosso usando l'operatore - =.

I tipi delegati derivano dalla classe Delegati in .NET Framework. I tipi delegati sono sigillati, non possono essere derivati. Poiché il delegato istanziato è un oggetto, può essere passato come parametro o assegnato a una proprietà. Ciò consente a un metodo di accettare un delegato come parametro e di chiamarlo in un secondo momento. Questo è noto come callback asincrono.


1

Una grande spiegazione e un'implementazione pratica del modello Delegato sono disponibili nelle Classi di inoltro delle raccolte di Google (anche, il modello Decoratore).


1

Nella comunicazione degli eventi il ​​mittente non sa quale oggetto gestirà l'evento. Il delegato è un tipo che contiene il riferimento al metodo. Delegato ha la firma e contiene riferimenti al metodo che corrisponde alla sua firma, quindi Delegato è come un puntatore a funzione sicura.

button1.Click + = new System.EventHandler (button1_Click) System.EventHandler è dichiarato qui come delegato In .net Events lavora sul concetto di delegato (come Button Click)

Il delegato viene utilizzato quando non si conosce il codice da richiamare in fase di esecuzione, quindi in quel momento viene utilizzato il delegato per gestire gli eventi

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


1

Un oggetto delegato è un oggetto che un altro oggetto consulta quando accade qualcosa in quell'oggetto. Ad esempio, il tuo riparatore è il tuo delegato se succede qualcosa alla tua auto. vai dal tuo riparatore e gli chiedi di riparare l'auto per te (anche se alcuni preferiscono riparare l'auto da soli, nel qual caso, sono i loro delegati per la loro auto).


1

Un delegato è un oggetto che rappresenta un puntatore a una funzione. Tuttavia, non è un normale puntatore a funzioni in quanto:

1) È orientato agli oggetti

2) È sicuro, ovvero può solo indicare un metodo e non è possibile leggere l'indirizzo di memoria grezza a cui punta

3) È fortemente tipizzato. Può solo indicare metodi che corrispondono alle sue firme.

4) Può indicare più di un metodo contemporaneamente.


1

I delegati vengono utilizzati principalmente con gli eventi.

La necessità è:

Non si desidera eseguire un pezzo di codice nel momento in cui si esegue il programma. Dopo aver eseguito il programma, si desidera eseguire quel pezzo di codice ogni volta che si verifica un evento.

Esempio :

  1. Applicazione console : il codice può essere eseguito solo al momento dell'esecuzione del programma. (Scritto all'interno del metodo principale)
  2. Applicazione Windows (programmazione dell'interfaccia utente) - il codice può essere eseguito facendo clic sul pulsante dopo aver eseguito il programma.

Questo è quello che dicono, non sai quale metodo invocherà al momento della compilazione. lo sai solo in fase di esecuzione che è quando si fa clic sul pulsante.

Senza delegati non è possibile alcuna programmazione dell'interfaccia utente. Perché stai eseguendo il codice ogni volta che l'utente fa eventi facendo clic sul pulsante, digitando nella casella di testo, selezionando l'elenco a discesa e così via ....


0

Un delegato è qualcosa a cui viene delegata un'attività. Lo scopo principale della delega è disaccoppiare il codice e consentire una maggiore flessibilità e riutilizzo.

Nella programmazione, e in particolare nella programmazione orientata agli oggetti, ciò significa che quando un metodo viene chiamato per fare un po 'di lavoro, passa il lavoro al metodo di un altro oggetto a cui ha un riferimento. Il riferimento potrebbe indicare qualsiasi oggetto desideriamo, purché l'oggetto sia conforme a un insieme predefinito di metodi. Lo chiamiamo "programmazione a un'interfaccia" (rispetto alla programmazione per un'implementazione di classe concreta). Un'interfaccia è fondamentalmente un modello generico e non ha implementazione; significa semplicemente una ricetta, un insieme di metodi, precondizioni e postcondizioni (regole).

Esempio semplice:

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();
   }
}

Ora vedi che posso usare qualsiasi implementazione che voglio in qualsiasi momento senza cambiare il codice in SomeCaller perché il tipo che doIt()viene passato non è concreto ma piuttosto astratto poiché è un'interfaccia. Nel mondo Java, questo è spesso espresso nel paradigma del servizio in cui si chiama un servizio (un oggetto che si fa pubblicità come servizio tramite un'interfaccia specifica) e il servizio quindi chiama i delegati per aiutarlo a fare il suo lavoro. I metodi del servizio sono denominati come attività a grana grossa (makePayment (), createNewUser (), ecc.), Mentre internamente fa molto se la nitidezza funziona attraverso la delega, con i tipi dei delegati che sono interfacce invece che implementazioni concrete.

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

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

(NB: Il modo in cui un'implementazione viene assegnata va oltre lo scopo di questo thread. Inversione di ricerca del controllo e iniezione di dipendenza.)


-2

Sebbene non sia in realtà un "puntatore a funzione", un delegato potrebbe apparire come questo è un linguaggio dinamico come PHP:



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

function foo() {
    print 'foo';
}

o in JavaScript potresti fare qualcosa del tipo:


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


2
Questo non è un esempio di delega. Nel tuo esempio, stai usando quella che viene chiamata una funzione variabile che sostanzialmente cerca una funzione con lo stesso nome della stringa a cui fa riferimento una variabile. Vedi funzioni variabili: php.net/manual/en/functions.variable-functions.php
Aquarelle
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.