Is using Action.Invoke considered best practice?

后端 未结 4 2015
故里飘歌
故里飘歌 2020-12-15 03:27

If I have the below code, should I just call the Action or should it call Action.Invoke?

public class ClassA
{
  public event Action OnAdd;

           


        
相关标签:
4条回答
  • 2020-12-15 03:51

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

    0 讨论(0)
  • 2020-12-15 03:53

    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.

    0 讨论(0)
  • 2020-12-15 04:01

    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")
    
    0 讨论(0)
  • 2020-12-15 04:03

    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");
      }
    }
    
    0 讨论(0)
提交回复
热议问题