62 votes

action <T> vs événement délégué

J'ai vu des développeurs utiliser les codes ci-dessous assez alternativement. Quelle est la différence exacte entre celles-ci et celles qui correspondent à la norme? Sont-ils les mêmes, comme Action et Func<T> est aussi un délégué:

 public event Action<EmployeeEventAgs> OnLeave;
public void Leave()
{
    OnLeave(new EmployeeEventAgs(this.ID));
}
 

CONTRE

 public delegate void GoOnLeave(EmployeeEventAgs e);
public event GoOnLeave OnLeave;
public void Leave()
{
    OnLeave(new EmployeeEventAgs(this.ID));
}
 

59voto

Hans Passant Points 475940

Fwiw, ni exemple utilise la norme .NET conventions. L' EventHandler<T> générique doit déclarer l'événement:

public event EventHandler<EmployeeEventArgs> Leave;

Le préfixe "on" devrait être réservé à une méthode protégée qui déclenche l'événement:

protected virtual void OnLeave(EmployeeEventArgs e) {
    var handler = Leave;
    if (handler != null) handler(this, e);
}

Vous n'avez pas avoir à le faire de cette façon, mais toute personne de reconnaître instantanément le modèle, de comprendre votre code et apprendre à utiliser et à personnaliser.

Et il a le grand avantage de ne pas être obligés de choisir entre un délégué personnalisé de déclaration et d' Action<>, EventHandler<> est le meilleur moyen. Qui répond à votre question.

37voto

Ivaylo Slavov Points 3505

Les deux lignes de code suivantes sont presque équivalents:

public event Action<EmployeeEventAgs> Leave;

par opposition à:

public event EventHandler<EmployeeEventAgs> Leave;

La différence est dans la signature de la méthode de gestionnaire d'événements. Si vous utilisez la première approche avec l'action, vous pourriez avoir:

public void LeaveHandler(EmployeeEventAgs e) { ... }

et puis ceci:

obj.Leave += LeaveHandler;

Avec la deuxième approche, la signature de l' LeaveHandler doit être différente:

public void LeaveHandler(object sender, EmployeeEventAgs e) { ... }

Il est très important de remarquer que, dans les deux cas, l' event mot-clé est présent. Un événement déclaré explicitement comme telles par l' event mot-clé n'est plus un champ de la classe. Au lieu de cela, il devient une propriété de l'évènement. L'événement propriétés sont semblables à celles des propriétés, sauf qu'ils n'ont pas d' get ou set accesseurs. Le compilateur permet de les utiliser uniquement sur le côté gauche d'un += et -= devoirs (ajout ou suppression d'un gestionnaire d'événement). Il n'y a aucun moyen de remplacer le déjà attribué des gestionnaires d'événements, ou d' invoquer l'événement à l'extérieur de la classe qui la déclare .

Si l'événement de mot-clé qui manquait dans les deux exemples, vous pouvez effectuer les opérations suivantes avec pas d'erreur ou d'avertissement:

obj.Leave = LeaveHandler;

qui va effacer toutes les gestionnaires et les remplacer avec de l' LeaveHandler.

En outre, vous pouvez également effectuer cet appel:

obj.Leave(new EmployeeEventAgs());

Les deux exemples ci-dessus sont considérées comme un anti-modèle, si vous avez l'intention de créer un événement. Un événement doit être invoqué que par le propriétaire de l'objet et ne devrait pas permettre à retrouver à l' élimination des abonnés. L' event mot-clé est le .NET-programme de construction qui vous permet de coller avec l'utilisation correcte des événements.

Avoir le dessus dans l'esprit, je crois que beaucoup de gens en tenir à l' EventHandler approche, car il est plus rare d'utiliser un EventHandler sans event mot-clé. Les Actions ont une portée plus large d'utilisation, ils ne sont pas aussi naturellement lorsqu'il est utilisé comme événements. Ce dernier est, bien sûr, un avis personnel, que le gestionnaire d'événement approche a sans doute devenu trop câblé dans mes pratiques de codage. Encore, si les actions sont utilisés correctement, il n'est pas un crime de l'utiliser pour des événements.

26voto

pdr Points 4795

L'action <T> est exactement la même chose que le délégué vide ... (T t)

Func <T> est exactement le même que le délégué T ... ()

8voto

Darryl Braaten Points 3344

L'action n'est qu'un raccourci pour la déclaration complète du délégué.

délégué public vide Action (T obj)

http://msdn.microsoft.com/en-us/library/018hxwa8.aspx

Lequel utiliser dépend des normes / du style de votre organisation.

4voto

Sky Sanders Points 19557

Oui, Action et Func sont simplement des délégués de commodité définis dans la 3.5 Clr.

Action, Func et lambdas ne sont que du sucre syntaxique et un avantage pour l’utilisation des délégués.

Il n'y a rien de magique en eux. Plusieurs personnes ont écrit de simples bibliothèques d’addon 2.0 pour ajouter cette fonctionnalité au code 2.0.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X