90

I'm curious about the differences between calling a Func<T> directly vs. using Invoke() on it. Is there a difference? Is the first syntactical sugar and calls Invoke() underneath anyway?

public T DoWork<T>(Func<T> method)
{
    return (T)method.Invoke();
}

vs.

public T DoWork<T>(Func<T> method)
{
    return (T)method();
}

Or am I on the wrong track entirely?

janw
  • 5,204
  • 5
  • 24
  • 43
tris
  • 1,460
  • 2
  • 16
  • 28
  • http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/f629c34d-6523-433a-90b3-bb5d445c5587 – D Stanley Apr 30 '13 at 21:34

2 Answers2

122

There's no difference at all. The second is just a shorthand for Invoke, provided by the compiler. They compile to the same IL.

Jon Skeet
  • 1,261,211
  • 792
  • 8,724
  • 8,929
  • 1
    Leaving the Invoke() method off is resulting in the compiler error: "Cannot implicitly convert type 'System.Func' to 'T' ". I'm compiling against .NET 4. – Mike Dec 06 '13 at 00:31
  • 2
    @Mike: That would happen if you'd missed the *brackets* off as well - i.e. tried to return `(T)method` rather than `(T)method()`. – Jon Skeet Dec 06 '13 at 06:44
  • @JonSkeet So is this guy wrong here: http://social.msdn.microsoft.com/Forums/en-US/f629c34d-6523-433a-90b3-bb5d445c5587/differences-between-delegate-invoke-and-call-a-method-directly?forum=csharplanguage – superlogical Dec 12 '13 at 19:53
  • 4
    @superlogical: There are two problems here. Firstly, the question there is about the difference between calling a method directly and calling it via a delegate. That's not the same as the difference between `foo()` and `foo.Invoke()` where `foo` is a variable of a delegate type. The other problem is that the *answer* seems to be talking about `Control.Invoke`, which isn't the same as calling `Invoke` on a delegate. – Jon Skeet Dec 13 '13 at 07:29
  • Has the OP edited his original post after reading Jon Skeet's comment? I can't track down what jon is referring to. – XDS Oct 27 '17 at 08:57
  • @xDisruptor: There are two pieces of code, and the OP is asking whether they're equivalent. My response is that they compile to the same IL. I'm not sure what's confusing you. – Jon Skeet Oct 27 '17 at 09:17
  • Upon reading your comment again I realized you were commenting on the link provided by superlogical - not the original post. For someone that is reading quickly through the comments it's not so clear what it is you are commenting on: "The answer seems to be talking about Control.Invoke etc)." – XDS Oct 27 '17 at 15:19
  • Which syntax do you prefer and why? I personally think that using `Invoke()` does not add anything in terms of readability or maintainability so I'd rather use the syntax without it. – Luca Cremonesi Nov 10 '17 at 17:04
  • 2
    @LucaCremonesi: If it's the result of a method call, I generally like `Invoke`, as `GetAction()()` looks weird, but `GetAction().Invoke()` looks okay. But I don't mind either way, for the most part. – Jon Skeet Nov 10 '17 at 17:05
21

Invoke works well with new C# 6 null propagation operator, now you can do

T result = method?.Invoke();

instead of

T result = method != null ? method() : null;
Electric Coffee
  • 10,583
  • 7
  • 59
  • 124
sanjuro
  • 1,504
  • 1
  • 19
  • 27
  • Can you illustrate a scenario where this is useful? The textbook case is raising events. – Gusdor Feb 25 '18 at 10:55
  • 2
    For example you can have an optional Func parameter that if no value is assigned, is the default(Func) which is null and is ignored. – Austin Salgat Mar 15 '19 at 16:00
  • 1
    It's the common case for events and other multi-cast delegates - they are usually initialized with null and gain non-null value after calling `+=`. So if you are going to fire an event and don't know if there are any subscriptions, the concise solution is to call `?.Invoke(...)`. – stop-cran Sep 16 '19 at 07:13