C# 使用 Action.Invoke 是否被视为最佳实践?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9259470/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is using Action.Invoke considered best practice?
提问by Jon
If I have the below code, should I just call the Action or should it call Action.Invoke?
如果我有下面的代码,我应该只调用 Action 还是应该调用 Action.Invoke?
public class ClassA
{
public event Action<string> 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
}
}
采纳答案by Rich O'Kelly
The two are equivalent, the compiler converts OnAdd("It Happened");into OnAdd.Invoke("It Happened");for you.
两者是等价的,编译器会为你转换OnAdd("It Happened");成OnAdd.Invoke("It Happened");。
I guess it's a matter of preference, however I personally prefer the terser form.
我想这是一个偏好问题,但我个人更喜欢更简洁的形式。
As an aside, it is generally preferable to take a local copy of a class level delegate before invoking it to avoid a race condition whereby OnAddis not null at the time that it is checked, but is at the time that it is invoked:
顺便说一句,通常最好在调用类级别委托之前获取类级别委托的本地副本,以避免出现竞争条件,OnAdd即在检查时不为空,但在调用时为空:
private void SomethingHappened()
{
Action<string> local = OnAdd;
if (local != null)
{
local("It Happened");
}
}
回答by Darin Dimitrov
The two constructs are perfectly equivalent.
这两种结构是完全等价的。
OnAdd("It Happened");
is just syntactic sugar. Behind the scenes the compiler emits a call to Action<T>.Invokein the resulting MSIL. So use the one that's more readable to you (for me OnAdd("It Happened");is readable enough).
只是语法糖。在幕后,编译器Action<T>.Invoke在生成的 MSIL 中发出调用。所以使用对你来说更易读的那个(对我来说OnAdd("It Happened");已经足够了)。
回答by Jon Skeet
They're exactly equivalent unless you run into a very strange bug around anonymous functions.
Personally I typicallyuse the shortcut form, but just occasionally it ends up being more readable to explicitly call Invoke. For example, you might have:
就我个人而言,我通常使用快捷方式,但只是偶尔显式调用Invoke. 例如,您可能有:
if (callAsync)
{
var result = foo.BeginInvoke(...);
// ...
}
else
{
foo.Invoke(...);
// ...
}
Here the explicit use of Invokeis useful for symmetry.
这里显式使用Invoke对对称很有用。
See section 15.4 of the C# 4 spec for more details of delegate invocation, although it doesn't explicitly specify it in terms of calling the Invokemethod.
有关委托调用的更多详细信息,请参阅 C# 4 规范的第 15.4 节,尽管它没有在调用Invoke方法方面明确指定它。
回答by jamespconnor
Something I noticed on this with the latest C# 6 release as it may encourage Invoketo be used more and thought I'd add it to this old question in case it helps someone:
我在最新的 C# 6 版本中注意到了这一点,因为它可能会鼓励Invoke更多地使用,并认为我会将它添加到这个旧问题中,以防它对某人有所帮助:
"Old" way:
“旧”方式:
Action<string> doSomething = null; // or not null
if (doSomething != null)
doSomething("test");
Possible pragmatic way (similar to empty event delegate pattern):
可能的实用方式(类似于空事件委托模式):
Action<string> doSomethingPragmatic = s => { }; // empty - might be overwritten later
doSomethingPragmatic("test");
C# 6:
C# 6:
Action<string> doSomethingCs6 = null; // or not null
doSomethingCs6?.Invoke("test");
// Not valid C#:
// doSomethingCs6?("test")
// doSomethingCs6?.("test")

