是否使用Action.Invoke被认为是最佳做法?

如果我有以下代码,我应该调用Action还是应该调用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(string Input) { //do something } } 

这两个是等价的,编译器转换OnAdd("It Happened"); 进入OnAdd.Invoke("It Happened"); 为了你。

我想这是一个偏好的问题,但我个人更喜欢这种forms。

顺便说一下,通常最好在调用它之前获取类级别委托的本地副本,以避免竞争条件,即OnAdd在检查时不是null,而是在调用它时:

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

这两个结构完全相同。

 OnAdd("It Happened"); 

只是语法糖。 在后台,编译器在生成的MSIL中发出对Action.Invoke的调用。 所以使用对你来说更具可读性的那个(对我来说OnAdd("It Happened");足够可读)。

我注意到最新的C#6版本,因为它可能会鼓励Invoke被更多地使用,并且我认为我会将它添加到这个旧问题,以防它帮助某人:

“旧”的方式:

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

可能的实用方法(类似于空事件委托模式):

 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") 

它们完全等效,除非你遇到一个围绕匿名函数的非常奇怪的错误 。

就个人而言,我通常使用快捷方式表单,但有时它最终会更明显地调用Invoke更具可读性。 例如,您可能有:

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

这里显式使用Invoke对于对称非常有用。

有关委托调用的更多详细信息,请参阅C#4规范的第15.4节,尽管它没有在调用Invoke方法方面明确指定它。