Func <T> () frente a Func <T> .Invoke ()

82

Tengo curiosidad por las diferencias entre llamar a un Func directamente y usar Invoke () en él. Hay una diferencia ? ¿Es el primero, el azúcar sintáctico y las llamadas Invoke () debajo de todos modos?

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

vs

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

O estoy completamente equivocado :) Gracias.

tris
fuente

Respuestas:

111

No hay ninguna diferencia. El segundo es solo una abreviatura de Invoke, proporcionado por el compilador. Se compilan en el mismo IL.

Jon Skeet
fuente
1
Dejar el método Invoke () desactivado da como resultado el error del compilador: "No se puede convertir implícitamente el tipo 'System.Func <T>' en 'T'". Estoy compilando contra .NET 4.
Mike
2
@Mike: Eso sucedería si también hubiera omitido los corchetes , es decir, si hubiera intentado regresar en (T)methodlugar de hacerlo (T)method().
Jon Skeet
@JonSkeet Entonces, ¿este tipo se equivoca aquí: social.msdn.microsoft.com/Forums/en-US/…
superlogical
4
@superlogical: Aquí hay dos problemas. En primer lugar, la pregunta es sobre la diferencia entre llamar a un método directamente y llamarlo a través de un delegado. Eso no es lo mismo que la diferencia entre foo()y foo.Invoke()dónde fooes una variable de un tipo de delegado. El otro problema es que la respuesta parece estar hablando Control.Invoke, que no es lo mismo que llamar Invokea un delegado.
Jon Skeet
2
@LucaCremonesi: Si es el resultado de una llamada a un método, generalmente me gusta Invoke, ya que se GetAction()()ve extraño, pero se GetAction().Invoke()ve bien. Pero no me importa de ninguna manera, en su mayor parte.
Jon Skeet
17

Invoke funciona bien con el nuevo operador de propagación nula de C # 6, ahora puede hacerlo

T result = method?.Invoke();

en vez de

T result = method != null ? method() : null;
sanjuro
fuente
¿Puede ilustrar un escenario en el que esto sea útil? El caso de los libros de texto está provocando eventos.
Gusdor
1
Por ejemplo, puede tener un parámetro Func opcional que si no se asigna ningún valor, es el predeterminado (Func) que es nulo y se ignora.
Austin Salgat
1
Es el caso común de los eventos y otros delegados de multidifusión: generalmente se inicializan con nulo y obtienen un valor no nulo después de la llamada +=. Entonces, si va a disparar un evento y no sabe si hay alguna suscripción, la solución concisa es llamar ?.Invoke(...).
stop-cran