是否使用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
的调用。 所以使用对你来说更具可读性的那个(对我来说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
方法方面明确指定它。