Func <T> () vs Func <T> .Invoke ()

82

Ich bin gespannt auf die Unterschiede zwischen dem direkten Aufrufen eines Func und der Verwendung von Invoke (). Ist da ein Unterschied ? Ist der erste syntaktische Zucker und ruft Invoke () trotzdem darunter auf?

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

vs.

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

Oder bin ich ganz auf dem falschen Weg :) Danke.

tris
quelle

Antworten:

111

Es gibt überhaupt keinen Unterschied. Die zweite ist nur eine Abkürzung für Invoke, die vom Compiler bereitgestellt wird. Sie kompilieren zu derselben IL.

Jon Skeet
quelle
1
Wenn Sie die Invoke () -Methode deaktivieren, wird der Compilerfehler angezeigt: "Typ 'System.Func <T>' kann nicht implizit in 'T' konvertiert werden". Ich kompiliere gegen .NET 4.
Mike
2
@Mike: Das würde passieren, wenn Sie auch die Klammern verpasst hätten - dh versucht hätten, zurückzukehren, (T)methodanstatt (T)method().
Jon Skeet
@ JonSkeet Also ist dieser Kerl hier falsch: social.msdn.microsoft.com/Forums/en-US/…
superlogical
4
@superlogical: Hier gibt es zwei Probleme. Erstens stellt sich die Frage nach dem Unterschied zwischen dem direkten Aufrufen einer Methode und dem Aufrufen über einen Delegaten. Dies ist nicht dasselbe wie der Unterschied zwischen foo()und foo.Invoke()wo fooeine Variable eines Delegatentyps ist. Das andere Problem ist, dass die Antwort zu sprechen scheint Control.Invoke, was nicht dasselbe ist, als Invokeeinen Delegierten anzurufen.
Jon Skeet
2
@ LucaCremonesi: Wenn es das Ergebnis eines Methodenaufrufs ist, mag ich im Allgemeinen Invoke, wie GetAction()()seltsam aussieht, aber in GetAction().Invoke()Ordnung aussieht. Aber es macht mir größtenteils nichts aus.
Jon Skeet
17

Invoke funktioniert gut mit dem neuen C # 6-Nullpropagationsoperator. Jetzt können Sie dies tun

T result = method?.Invoke();

anstatt

T result = method != null ? method() : null;
Sanjuro
quelle
Können Sie ein Szenario veranschaulichen, in dem dies nützlich ist? Der Lehrbuchfall löst Ereignisse aus.
Gusdor
1
Beispielsweise können Sie einen optionalen Func-Parameter verwenden, der, wenn kein Wert zugewiesen ist, der Standardwert (Func) ist, der null ist und ignoriert wird.
Austin Salgat
1
Dies ist der übliche Fall bei Ereignissen und anderen Delegierten mit mehreren Besetzungen. Sie werden normalerweise mit null initialisiert und erhalten nach dem Aufruf einen Wert ungleich Null +=. Wenn Sie also ein Ereignis auslösen und nicht wissen, ob Abonnements vorhanden sind, können Sie es kurz anrufen ?.Invoke(...).
Stop-Cran