49
delegate void DelegateTest();

DelegateTest delTest;

Whats the difference between calling delTest.Invoke() and delTest()? Both would execute the delegate on the current thread, right?

Kyle Trauberman
  • 25,414
  • 13
  • 85
  • 121
remdao
  • 885
  • 3
  • 17
  • 23

4 Answers4

60

The delTest() form is a compiler helper, underneath it is really a call to Invoke().

Richard
  • 106,783
  • 21
  • 203
  • 265
  • 3
    @Richard: What does Invoke() internally do. Where does this Invoke method exactly reside. I did not find in the metadata file of Delegate as well as MultiCastDelegate. – Novice Mar 16 '11 at 06:44
  • 3
    @Jose: They are part of the internal implementation of the CLR, probably directly understood by the JIT compiler. – Richard Mar 16 '11 at 08:18
  • @Richard: Thanks for the reply. Later i came across a similar question posted in SO. One more question, what does DynamicInvoke of delegate do? I read in some forums and they have talked about late-bound. I didn't understand its usage. – Novice Mar 16 '11 at 09:33
  • @Jose: It is the delegate equivalent of MethodInfo.Invoke when using reflection to dynamically execute methods: passing parameters as `obbject[]` and returning `object`. – Richard Mar 16 '11 at 09:43
  • My old prof would refer to this as "syntactic sugar". – Drazen Bjelovuk May 18 '16 at 03:26
23

Richard's answer is correct, however starting with C# 6.0, there is one situation where using Invoke() directly could be advantageous due to the addition of the null conditional operator. Per the MS docs:

Another use for the null-conditional member access is invoking delegates in a thread-safe way with much less code. The old way requires code like the following:

var handler = this.PropertyChanged;
if (handler != null)  
    handler(…);

The new way is much simpler:

PropertyChanged?.Invoke(…)   

The new way is thread-safe because the compiler generates code to evaluate PropertyChanged one time only, keeping the result in a temporary variable. You need to explicitly call the Invoke method because there is no null-conditional delegate invocation syntax PropertyChanged?(e).

Palec
  • 12,743
  • 8
  • 69
  • 138
John Smith
  • 7,243
  • 6
  • 49
  • 61
3

That's correct. Both have the exact same result.

Given that you have properly initialized delTest of course.

Ronald Wildenberg
  • 31,634
  • 14
  • 90
  • 133
  • 1
    If `delTest` is `null`, both syntaxes again lead to the same result (which is in that situation a `NullReferenceException` thrown from the line where the invocation is attempted). – Jeppe Stig Nielsen Feb 27 '15 at 09:16
3

Delegate.Invoke and Delegate() are identical. both do the same thing . see the bellow code

static async Task Main(string[] args)
{
   MyDelegate mydelegate = new MyDelegate(CallMe);
   mydelegate.Invoke("Reza");
   mydelegate("Reza");
}

public delegate void MyDelegate(string message);
public static void CallMe(string message)
{
}

IL

IL_001a: ldarg.0
IL_001b: ldfld class TestConsole.Program/MyDelegate TestConsole.Program/'<Main>d__1'::'<mydelegate>5__1'
IL_0020: ldstr "Reza"
IL_0025: callvirt instance void TestConsole.Program/MyDelegate::Invoke(string)
IL_002a: nop
IL_002b: ldarg.0
IL_002c: ldfld class TestConsole.Program/MyDelegate TestConsole.Program/'<Main>d__1'::'<mydelegate>5__1'
IL_0031: ldstr "Reza"
IL_0036: callvirt instance void TestConsole.Program/MyDelegate::Invoke(string)
IL_003b: nop

I usually use Invoke() because you can use the null-check and people reading through the code can more easily see that a delegate is being use.

null-check

MyDelegate mydelegate = null;
mydelegate?.Invoke("Reza");
mydelegate("Reza"); // Error: System.NullReferenceException
Reza Jenabi
  • 3,884
  • 1
  • 29
  • 34