C # connaît deux termes, delegate
et event
. Commençons par le premier.
Déléguer
A delegate
est une référence à une méthode. Tout comme vous pouvez créer une référence à une instance:
MyClass instance = myFactory.GetInstance();
Vous pouvez utiliser un délégué pour créer une référence à une méthode:
Action myMethod = myFactory.GetInstance;
Maintenant que vous avez cette référence à une méthode, vous pouvez appeler la méthode via la référence:
MyClass instance = myMethod();
Mais pourquoi le feriez-vous? Vous pouvez également simplement appeler myFactory.GetInstance()
directement. Dans ce cas, vous le pouvez. Cependant, il existe de nombreux cas où vous ne souhaitez pas que le reste de l'application connaisse myFactory
ou appelle myFactory.GetInstance()
directement.
Un élément évident est si vous voulez pouvoir remplacer myFactory.GetInstance()
à myOfflineFakeFactory.GetInstance()
partir d'un endroit central (aka modèle de méthode d'usine ).
Modèle de méthode d'usine
Donc, si vous avez une TheOtherClass
classe et qu'elle doit utiliser le myFactory.GetInstance()
, voici à quoi ressemblera le code sans délégués (vous devrez faire TheOtherClass
connaître le type de votre myFactory
):
TheOtherClass toc;
//...
toc.SetFactory(myFactory);
class TheOtherClass
{
public void SetFactory(MyFactory factory)
{
// set here
}
}
Si vous utilisez des délégués, vous n'avez pas à exposer le type de mon usine:
TheOtherClass toc;
//...
Action factoryMethod = myFactory.GetInstance;
toc.SetFactoryMethod(factoryMethod);
class TheOtherClass
{
public void SetFactoryMethod(Action factoryMethod)
{
// set here
}
}
Ainsi, vous pouvez donner un délégué à une autre classe à utiliser, sans leur exposer votre type. La seule chose que vous exposez est la signature de votre méthode (combien de paramètres vous avez, etc.).
"Signature de ma méthode", où ai-je entendu ça avant? O oui, les interfaces !!! les interfaces décrivent la signature d'une classe entière. Considérez les délégués comme décrivant la signature d'une seule méthode!
Une autre grande différence entre une interface et un délégué est que lorsque vous écrivez votre classe, vous n'avez pas à dire à C # "cette méthode implémente ce type de délégué". Avec les interfaces, vous devez dire "cette classe implémente ce type d'interface".
En outre, une référence de délégué peut (avec certaines restrictions, voir ci-dessous) référencer plusieurs méthodes (appelées MulticastDelegate
). Cela signifie que lorsque vous appelez le délégué, plusieurs méthodes explicitement attachées seront exécutées. Une référence d'objet ne peut toujours faire référence qu'à un seul objet.
Les restrictions pour a MulticastDelegate
sont que la signature (méthode / délégué) ne doit pas avoir de valeur de retour ( void
) et les mots clés out
et ref
n'est pas utilisée dans la signature. De toute évidence, vous ne pouvez pas appeler deux méthodes qui renvoient un nombre et s'attendre à ce qu'elles renvoient le même numéro. Une fois la signature conforme, le délégué est automatiquement a MulticastDelegate
.
un événement
Les événements ne sont que des propriétés (comme le get; set; les propriétés des champs d'instance) qui exposent l'abonnement au délégué d'autres objets. Cependant, ces propriétés ne prennent pas en charge get; set ;. Au lieu de cela, ils prennent en charge l'ajout; retirer;
Vous pouvez donc avoir:
Action myField;
public event Action MyProperty
{
add { myField += value; }
remove { myField -= value; }
}
Utilisation dans l'interface utilisateur (WinForms, WPF, UWP ainsi de suite)
Donc, maintenant nous savons qu'un délégué est une référence à une méthode et que nous pouvons avoir un événement pour faire savoir au monde qu'il peut nous donner ses méthodes à référencer à partir de notre délégué, et nous sommes un bouton d'interface utilisateur, alors: nous peut demander à toute personne intéressée de savoir si j'ai été cliquée, d'enregistrer sa méthode avec nous (via l'événement que nous avons exposé). Nous pouvons utiliser toutes les méthodes qui nous ont été données et les référencer par notre délégué. Et puis, nous attendrons et attendrons .... jusqu'à ce qu'un utilisateur vienne et clique sur ce bouton, nous aurons alors suffisamment de raisons d'invoquer le délégué. Et parce que le délégué fait référence à toutes ces méthodes qui nous sont données, toutes ces méthodes seront invoquées. Nous ne savons pas ce que font ces méthodes, ni nous savons quelle classe implémente ces méthodes. Tout ce qui nous importe, c'est que quelqu'un était intéressé à ce qu'on clique sur nous,
Java
Les langages comme Java n'ont pas de délégués. Ils utilisent plutôt des interfaces. La façon dont ils le font est de demander à toute personne intéressée par `` qu'on clique '', d'implémenter une certaine interface (avec une certaine méthode que nous pouvons appeler), puis de nous donner l'instance entière qui implémente l'interface. Nous gardons une liste de tous les objets implémentant cette interface et pouvons appeler leur «certaine méthode que nous pouvons appeler» chaque fois que nous cliquons.