Is using Action.Invoke considered best practice?

孤街醉人 提交于 2019-12-30 01:43:46

问题


If I have the below code, should I just call the Action or should it call 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
  }  
}

回答1:


The two are equivalent, the compiler converts OnAdd("It Happened"); into OnAdd.Invoke("It Happened"); for you.

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 OnAdd is not null at the time that it is checked, but is at the time that it is invoked:

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



回答2:


The two constructs are perfectly equivalent.

OnAdd("It Happened");

is just syntactic sugar. Behind the scenes the compiler emits a call to Action<T>.Invoke in the resulting MSIL. So use the one that's more readable to you (for me OnAdd("It Happened"); is readable enough).




回答3:


Something I noticed on this with the latest C# 6 release as it may encourage Invoke to be used more and thought I'd add it to this old question in case it helps someone:

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

Action<string> doSomethingCs6 = null; // or not null
doSomethingCs6?.Invoke("test");

// Not valid C#:
// doSomethingCs6?("test")
// doSomethingCs6?.("test")



回答4:


They're exactly equivalent unless you run into a very strange bug around anonymous functions.

Personally I typically use the shortcut form, but just occasionally it ends up being more readable to explicitly call Invoke. For example, you might have:

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

Here the explicit use of Invoke is useful for symmetry.

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 Invoke method.



来源:https://stackoverflow.com/questions/9259470/is-using-action-invoke-considered-best-practice

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!