L’utilisation d’Action.Invoke est-elle considérée comme la meilleure pratique?

Si j’ai le code ci-dessous, devrais-je simplement appeler Action ou devrait-il appeler Action.Invoke?

public class ClassA { public event Action OnAdd; private void SomethingHappened() { if (OnAdd != null) OnAdd("It Happened"); //Should it be OnAdd.Invoke("It Happened") ??????? } } public class ClassB { public ClassB() { var myClass = new ClassA(); myClass.OnAdd += Add; } private void Add(ssortingng Input) { //do something } } 

Les deux sont équivalents, le compilateur convertit OnAdd("It Happened"); into OnAdd.Invoke("It Happened"); pour vous.

Je suppose que c’est une question de préférence, mais personnellement, je préfère la forme terser.

En passant, il est généralement préférable de prendre une copie locale d’un délégué de niveau de classe avant de l’invoquer pour éviter une condition de OnAdd laquelle OnAdd n’est pas null au moment où il est vérifié, mais au moment où il est appelé:

 private void SomethingHappened() { Action local = OnAdd; if (local != null) { local("It Happened"); } } 

Les deux constructions sont parfaitement équivalentes.

 OnAdd("It Happened"); 

est juste du sucre syntaxique. En coulisse, le compilateur émet un appel à Action.Invoke dans le MSIL résultant. Alors utilisez celui qui est le plus lisible pour vous (pour moi, OnAdd("It Happened"); est assez lisible).

Quelque chose que j’ai remarqué à ce sujet dans la dernière version de C # 6 pourrait encourager Invoke à être davantage utilisé et j’ai pensé l’append à cette vieille question au cas où cela aiderait quelqu’un:

“Vieux” façon:

 Action doSomething = null; // or not null if (doSomething != null) doSomething("test"); 

Manière pragmatique possible (similaire au modèle de délégué d’événement vide):

 Action doSomethingPragmatic = s => { }; // empty - might be overwritten later doSomethingPragmatic("test"); 

C # 6:

 Action doSomethingCs6 = null; // or not null doSomethingCs6?.Invoke("test"); // Not valid C#: // doSomethingCs6?("test") // doSomethingCs6?.("test") 

Ils sont exactement équivalents à moins que vous ne renconsortingez un bogue très étrange concernant les fonctions anonymes .

Personnellement, j’utilise typiquement le raccourci, mais il arrive parfois qu’il soit plus lisible pour appeler explicitement Invoke . Par exemple, vous pourriez avoir:

 if (callAsync) { var result = foo.BeginInvoke(...); // ... } else { foo.Invoke(...); // ... } 

Ici, l’utilisation explicite de Invoke est utile pour la symésortinge.

Voir la section 15.4 de la spécification C # 4 pour plus de détails sur l’invocation de délégué, bien qu’elle ne le spécifie pas explicitement en termes d’appel de la méthode Invoke .