Question

Supposons que nous ayons:

interface Foo 
{
 bool Func(int x);
}

class Bar: Foo
{
  bool Func(int x)
  {
   return (x>0);
  }  
}

class Baz: Foo
{
  bool Func(int x)
  {
   return (x<0);
  }  
}

Nous pouvons maintenant lancer Bar et Baz en tant que Foos et appeler leurs méthodes Func.

Les délégués simplifient un peu ceci:

delegate bool Foo(int x);

bool Bar(int x)
{
 return (x<0);
}

bool Baz(int x)
{
 return (x>0);
}

Nous pouvons maintenant faire le tour de Bar et Baz en tant que délégués Foo.

Quel est le véritable avantage des délégués, à l'exception d'un code plus court?

Était-ce utile?

La solution

Il y a une légère différence, les délégués peuvent accéder aux variables membres des classes dans lesquelles elles sont définies. En C # (contrairement à Java), toutes les classes internes sont considérées comme statiques. Par conséquent, si vous utilisez une interface pour gérer un rappel, par exemple, un ActionListener pour un bouton. La classe interne d'implémentation doit être transmise (via le constructeur) aux références aux parties de la classe contenante avec lesquelles elle peut avoir besoin d'interagir pendant le rappel. Les délégués ne disposent pas de cette restriction, ce qui réduit la quantité de code nécessaire à la mise en œuvre du rappel.

Un code plus court et plus concis est également un avantage non négligeable.

Autres conseils

Du point de vue du génie logiciel, vous avez raison, les délégués ressemblent beaucoup aux interfaces de fonction en ce qu’ils prototypent une interface de fonction.

Ils peuvent également être utilisés de la même manière: au lieu de transmettre une classe entière contenant la méthode dont vous avez besoin, vous pouvez ne transmettre qu’un délégué. Cela économise beaucoup de code et crée un code beaucoup plus lisible.

De plus, avec l’avènement des expressions lambda, elles peuvent maintenant aussi être définies facilement à la volée, ce qui est un énorme bonus. Même s’il est POSSIBLE de construire des classes à la volée en C #, c’est vraiment une douleur énorme dans le dos.

La comparaison des deux est un concept intéressant. Je n'avais pas auparavant considéré à quel point les idées étaient similaires du point de vue de la structuration de code et de cas d'utilisation.

Un délégué partage beaucoup de points en commun avec une référence d'interface utilisant une seule méthode du point de vue de l'appelant.

Dans le premier exemple, Baz et Bar sont des classes qui peuvent être héritées et instanciées. Dans le deuxième exemple, Baz et Bar sont des méthodes.

Vous ne pouvez pas appliquer de références d'interface à n'importe quelle classe correspondant au contrat d'interface. La classe doit déclarer explicitement qu'elle prend en charge l'interface. Vous pouvez appliquer une référence de délégué à toute méthode correspondant à la signature.

Vous ne pouvez pas inclure de méthodes statiques dans un contrat d'interface. (Bien que vous puissiez utiliser des méthodes statiques avec des méthodes d'extension). Vous pouvez faire référence à des méthodes statiques avec une référence de délégué.

Non, les délégués sont pour les pointeurs de méthode. Ensuite, vous pouvez vous assurer que la signature de la méthode associée au délégué est correcte.

De plus, vous n'avez pas besoin de connaître la structure de la classe. De cette façon, vous pouvez utiliser une méthode que vous avez écrite pour la transmettre à une méthode d’une autre classe et définir les fonctionnalités souhaitées.

Consultez la Liste < > ; classe avec la méthode Find . Vous devez maintenant définir ce qui détermine si quelque chose correspond ou non, sans exiger que les éléments contenus dans la classe implémentent IListFindable ou quelque chose de similaire.

Vous pouvez passer les délégués comme paramètres dans des fonctions (Ok, techniquement, les délégués deviennent des objets lors de la compilation, mais ce n'est pas le problème ici). Vous pouvez passer un objet en tant que paramètre (évidemment), mais vous liez ensuite ce type d'objet à la fonction en tant que paramètre. Avec les délégués, vous pouvez transmettre toute fonction à exécuter dans le code ayant la même signature, quelle que soit son origine.

On peut considérer les délégués comme une interface pour une méthode qui définit les arguments et le type de retour qu'une méthode doit avoir pour s'adapter au délégué

Oui, un délégué peut être considéré comme une interface avec une méthode.

Un délégué est un pointeur de méthode typée. Cela vous donne plus de flexibilité que les interfaces, car vous pouvez tirer parti de la covariance et de la contravariance, et vous pouvez modifier l’état de l’objet (vous devez passer le pointeur this avec des foncteurs basés sur une interface).

De plus, les délégués disposent de nombreux sucres syntaxiques permettant de les combiner facilement.

Les interfaces et les délégués sont deux choses totalement différentes, bien que je comprenne la tentation de décrire les délégués en termes d’interface pour faciliter la compréhension ... Cependant, ne pas connaître la vérité peut être source de confusion à long terme.

Les délégués ont été inspirés (en partie) par le fait que l’art noir des méthodes C ++ était inadéquat pour certains objectifs. Un exemple classique consiste à mettre en œuvre un mécanisme de transmission de messages ou de gestion d’événements. Les délégués vous permettent de définir une signature de méthode sans aucune connaissance des types ou des interfaces d'une classe. Je pourrais définir un & Quot; void eventHandler (Event * e) & Quot; déléguez-le et invoquez-le dans n'importe quelle classe qui l'a implémenté.

Pour en savoir plus sur ce problème classique et sur les raisons pour lesquelles les délégués sont souhaitables, lisez ceci puis this .

Dans au moins une proposition visant à ajouter des fermetures (c'est-à-dire des délégués anonymes) à Java, elles équivalent à des interfaces avec une méthode à membre unique.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top