Qu'est-ce que Delegate? [fermé]

152

Je ne comprends pas quel est le rôle réel d'un délégué?

On m'a posé cette question plusieurs fois au cours de mes entretiens, mais je ne pense pas que les intervieweurs aient été satisfaits de ma réponse.

Quelqu'un peut-il me donner la meilleure définition, en une phrase, avec un exemple pratique?

Naveed
la source
21
par curiosité, qu'avez-vous répondu pour que nous puissions vous dire comment vous pouvez le corriger?
Anthony Forloney
6
Je trouve intéressant que cette question ait été fermée mais qu'elle ait 126 votes positifs et 65 personnes l'ont marquée comme favorite. On dirait que même si c'est trop large, c'est toujours une très bonne question.
Riche

Réponses:

171

J'aime penser à un délégué comme "un pointeur vers une fonction". Cela remonte à l'époque C, mais l'idée tient toujours.

L'idée est que vous devez être capable d'appeler un morceau de code, mais ce morceau de code que vous allez appeler n'est pas connu avant l'exécution. Vous utilisez donc un «délégué» à cette fin. Les délégués sont utiles pour des choses comme les gestionnaires d'événements, etc., où vous faites différentes choses en fonction de différents événements, par exemple.

Voici une référence pour C # que vous pouvez consulter:

En C #, par exemple, disons que nous avons eu un calcul que nous voulions faire et que nous voulions utiliser une méthode de calcul différente que nous ne connaissons pas avant l'exécution. Nous pourrions donc avoir quelques méthodes de calcul comme celle-ci:

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

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

Nous pourrions déclarer une signature de délégué comme ceci:

public delegate double calcTotalDelegate(double amt);

Et puis nous pourrions déclarer une méthode qui prend le délégué comme paramètre comme ceci:

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

Et nous pourrions appeler la CalcMyTotalméthode en passant la méthode déléguée que nous voulions utiliser.

double tot1 = CalcMyTotal(100.34, CalcTotalMethod1);
double tot2 = CalcMyTotal(100.34, CalcTotalMethod2);
Console.WriteLine(tot1);
Console.WriteLine(tot2);
dcp
la source
19
+1 pour le clin d'œil au pointeur de fonction simple mais efficace en C.
Aiden Bell
3
Une question liée à votre réponse. En quoi est-ce vraiment différent d'appeler une fonction de manière normale? Juste à cause de cela, il n'est pas connu au moment de l'exécution?
Naveed le
1
@NAVEED - référez-vous à ma dernière modification, j'ai inclus un exemple. En ce qui concerne l'appel de méthode réel, il n'a pas l'air différent d'un appel de méthode normal dans mon exemple ci-dessus (le calcTotal (amt) appelle le délégué), mais le pouvoir des délégués est que vous pouvez les utiliser comme paramètres, etc. lorsque vous voulez qu'une méthode puisse avoir un comportement différent. Il y a beaucoup d'autres choses pour lesquelles vous pouvez également les utiliser, ce n'est qu'un simple exemple. J'espère que cela pourra aider.
dcp le
Ce n'est pas connu au moment de l'exécution, et c'est une fonction liée plutôt qu'une fonction libre - assigner une méthode non statique Fooà un délégué appellera this.Foo()plutôt qu'une fonction statique comme le ferait un pointeur de fonction (en C, vous avez souvent un void*paramètre supplémentaire pour passer thisau pointeur de fonction)
Pete Kirkham
1
+1 pour l'exemple rapide et efficace établissant des similitudes avec des pointeurs de fonction en C / C ++. Très appréciée!
G21 du
19

un délégué est simplement un pointeur de fonction.
mettez simplement vous attribuez la méthode que vous souhaitez exécuter votre délégué. puis plus tard dans le code, vous pouvez appeler cette méthode via Invoke.

du code pour démontrer (écrit ceci de mémoire afin que la syntaxe puisse être désactivée)

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
la source
16

Pris d'ici

Q Que sont les délégués?
A Lorsqu'un objet reçoit une demande, l'objet peut soit gérer la demande lui-même, soit transmettre la demande à un deuxième objet pour effectuer le travail. Si l'objet décide de transmettre la demande, vous dites que l'objet a transféré la responsabilité du traitement de la demande au deuxième objet.

Ou, comme pseudo-exemple simple: quelque chose envoie une requête à object1. object1 transmet ensuite la demande et lui-même à object2 - le délégué. object2 traite la demande et effectue un certain travail. (note: le lien ci-dessus donne de bons exemples)

Anthony Forloney
la source
L'exemple donné dans le lien ci-dessus n'indique pas correctement la délégation.
Hardik9850
4

Pensez au délégué comme à une implémentation simplifiée du modèle de commande.

Vitaliy Liptchinsky
la source
4

Un délégué est un objet qui peut faire référence à une méthode. Ainsi, lorsque nous créons un délégué, nous créons un objet pouvant contenir une référence à une méthode. De plus, la méthode peut être appelée via cette référence. Ainsi, un délégué peut appeler la méthode à laquelle il fait référence. Le principal avantage d'un délégué est qu'il nous permet de spécifier un appel à une méthode, mais la méthode réellement invoquée est déterminée au moment de l'exécution et non au moment de la compilation.

Délégué simple

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
la source
2

Ici, je vais expliquer les délégués, les délégués multicast et leur utilisation. Delegate est un type qui contient la ou les méthodes de référence dans un objet. Il est également appelé pointeur de fonction de type sécurisé. Nous pouvons dire qu'un délégué est un type qui définit une signature de méthode.

Lorsque vous instanciez un délégué, vous pouvez associer son instance à n'importe quelle méthode avec une signature compatible. Vous pouvez invoquer (ou appeler) la méthode via l'instance de délégué. Les délégués sont utilisés pour passer des méthodes comme arguments à d'autres méthodes. Les gestionnaires d'événements ne sont rien de plus que des méthodes qui sont appelées via des délégués. Les avantages de l'utilisation des délégués sont: Encapsulation de l'appel de la méthode à partir de l'appelant L'utilisation efficace du délégué améliore les performances de l'application Utilisé pour appeler une méthode de manière asynchrone. Certaines propriétés des délégués sont

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.

public delegate type_of_delegate delegate_name () // Déclaration

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'exemple suivant montre une opération de délégué:

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

Qu'est-ce que le délégué de multidiffusion?

C'est un délégué qui détient la référence de plus d'une méthode. Les délégués de multidiffusion doivent contenir uniquement des méthodes qui retournent void, sinon il y a une exception d'exécution.

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

Ici, le délégué est ajouté à l'aide de l'opérateur + = et supprimé à l'aide de l'opérateur - =.

Les types de délégués sont dérivés de la classe Delegate dans le .NET Framework. Les types de délégués sont scellés - ils ne peuvent pas être dérivés. Étant donné que le délégué instancié est un objet, il peut être passé en tant que paramètre ou affecté à une propriété. Cela permet à une méthode d'accepter un délégué en tant que paramètre et d'appeler le délégué ultérieurement. C'est ce qu'on appelle un rappel asynchrone.

Jom George
la source
1

Une bonne explication et une mise en œuvre pratique du modèle Delegate peuvent être trouvées dans les classes de transfert de collections Google (également, le modèle Decorator).

Carl
la source
1

Dans la communication événementielle, l'expéditeur ne sait pas quel objet gérera l'événement. Le délégué est le type qui contient la référence de la méthode. Delegate a une signature et contient une référence à la méthode qui correspond à sa signature, donc Delegate est comme un pointeur de fonction de type sécurisé.

button1.Click + = new System.EventHandler (button1_Click) System.EventHandler est déclaré en tant que délégué ici Dans .net Events travaille sur le concept de Delegate (comme Button Click)

Delegate est utilisé lorsque vous ne savez pas quel code appeler au moment de l'exécution Donc, à ce moment-là, Delegate est utilisé pour gérer les événements

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

Yogesh
la source
1

Un objet délégué est un objet qu'un autre objet consulte lorsque quelque chose se produit dans cet objet. Par exemple, votre réparateur est votre délégué si quelque chose arrive à votre voiture. vous allez chez votre réparateur et lui demandez de réparer la voiture pour vous (bien que certains préfèrent réparer la voiture eux-mêmes, auquel cas ils sont leur propre délégué pour leur voiture).


la source
1

Un délégué est un objet qui représente un pointeur vers une fonction. Cependant, ce n'est pas un pointeur de fonction ordinaire en ce sens qu'il:

1) Est orienté objet

2) Est de type sécurisé, c'est-à-dire qu'il ne peut pointer que sur une méthode et que vous ne pouvez pas lire l'adresse mémoire brute vers laquelle il pointe

3) Est fortement typé. Il ne peut pointer que vers des méthodes qui correspondent à ses signatures.

4) Peut pointer vers plus d'une méthode en même temps.

Refroidisseur d'eau v2
la source
1

Les délégués sont principalement utilisés lors d'événements.

Le besoin est:

Vous ne souhaitez pas exécuter un morceau de code au moment où vous exécutez le programme. Après avoir exécuté le programme, vous souhaitez exécuter ce morceau de code chaque fois qu'un événement se produit.

Exemple :

  1. Application console - le code ne peut être exécuté qu'au moment où vous exécutez le programme. (Écrit dans la méthode principale)
  2. Application Windows (programmation de l'interface utilisateur) - le code peut être exécuté en cliquant sur le bouton après l'exécution du programme.

C'est ce qu'ils disent, vous ne savez pas quelle méthode invoquera au moment de la compilation. vous ne le savez qu'au moment de l'exécution, c'est-à-dire en cliquant sur le bouton.

Sans délégués, aucune programmation d'interface utilisateur n'est possible. Parce que vous exécutez du code chaque fois que l'utilisateur crée des événements en cliquant sur un bouton, en tapant dans la zone de texte, en sélectionnant un élément de liste déroulante, etc.

shathar khan
la source
0

Un délégué est un élément auquel une tâche est déléguée. L'objectif principal de la délégation est de découpler le code et de permettre une plus grande flexibilité et une plus grande réutilisation.

En programmation, et en particulier en programmation orientée objet, cela signifie que lorsqu'une méthode est appelée pour effectuer un travail, elle passe le travail à la méthode d'un autre objet auquel elle fait référence. La référence pourrait pointer vers l'objet que nous souhaitons, tant que l'objet est conforme à un ensemble prédéfini de méthodes. Nous l'appelons "programmation vers une interface" (par opposition à la programmation vers une implémentation de classe concrète). Une interface est essentiellement un modèle générique et n'a pas d'implémentation; cela signifie simplement une recette, un ensemble de méthodes, des conditions préalables et des post-conditions (règles).

Exemple simple:

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

Maintenant, vous voyez que je peux utiliser n'importe quelle implémentation que je veux à tout moment sans changer le code dans SomeCaller parce que le type qui doIt()est passé n'est pas concret mais plutôt abstrait puisqu'il s'agit d'une interface. Dans le monde Java, cela s'exprime souvent dans le paradigme du service où vous appelez un service (un objet s'annonçant comme un service via une interface spécifique) et le service appelle ensuite les délégués pour l'aider à faire son travail. Les méthodes du service sont nommées comme des tâches grossières (makePayment (), createNewUser (), etc.), tandis qu'en interne, il fait beaucoup de travail concret par délégation, les types des délégués étant des interfaces au lieu des implémentations concrètes.

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

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

(NB: la manière dont une implémentation est attribuée dépasse le cadre de ce thread. Inversion de recherche de contrôle et injection de dépendances.)

Aquarelle
la source
-2

Bien qu'il ne s'agisse pas vraiment d'un "pointeur de fonction", un délégué peut ressembler à un langage dynamique comme PHP:



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

function foo() {
    print 'foo';
}

ou en JavaScript, vous pouvez faire quelque chose comme:


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

mmattax
la source
2
Ce n'est pas un exemple de délégation. Dans votre exemple, vous utilisez ce qu'on appelle une fonction de variable qui recherche essentiellement une fonction ayant le même nom que la chaîne à laquelle une variable fait référence. Voir les fonctions variables: php.net/manual/en/functions.variable-functions.php
Aquarelle